conductor(track): init test_suite_cleanup_gemini_cli_removal_20260705 — 3-front cleanup track
3 fronts, 3 phases, 31 tasks, 12 verification criteria. Based on 3 parallel explore-agent audits of the live codebase. Front A — Gemini CLI Adapter Removal: delete src/gemini_cli_adapter.py + 7 test files; edit ai_client.py (3 functions + 8 dispatch branches + PROVIDERS 8->7); edit app_controller.py (~11 sites) + gui_2.py (2 blocks) + project_manager.py + api_hooks.py; introduce a mock provider that routes to tests/mock_gemini_cli.py so the 9 live_gui sim tests switch from gemini_cli to mock without losing their mock-LLM mechanism; update 7 docs + 5 conductor docs. Front B — Test Suite Cleanup (410 files, 2,133 tests, ~45-60 files downsizable): delete 2 guaranteed-broken chronology tests (import from deleted scripts.audit.*); consolidate 7 test_scavenge_*.py tautologies into 1 test_directive_structure.py; review deprecated-module tests; consolidate ~15 test_*_phase*.py one-offs; migrate 27 src.models shim importers to direct subsystem imports; extract shared mock_controller fixture from ~8 boilerplate-patch files; fix 3 fix-not-skip candidates (Gemini 503 in summarize.summarise_file); audit the 120KB test_gui_2_result.py (9.4% of suite line count in one file). Front C — Metadata-Type Reduction: flip the 38-site MCP dispatch inversion (dispatch()+22 consumers still call str wrappers, not the _result variants); migrate app_controller.py's ~40 in-memory Metadata state sites to typed per-aggregate dataclasses; fix aggregate.py file_items: list[Metadata] -> list[FileItem]; delete dead code (openai_schemas.to_legacy_dict, app_controller._push_mma_state_update). Out of scope: GEMINI_CLI_HOOK_CONTEXT env var + cli_tool_bridge.py + mma_exec.py (meta-tooling, not the provider — separate follow-up if user wants to purge naming).
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
{
|
||||
"track_id": "test_suite_cleanup_gemini_cli_removal_20260705",
|
||||
"name": "Test Suite Cleanup + Gemini CLI Adapter Removal + Metadata-Type Reduction",
|
||||
"status": "active",
|
||||
"branch": "master",
|
||||
"created": "2026-07-05",
|
||||
"owner": "Tier 1 (initialized); implementation delegated to Tier 2/3.",
|
||||
"blocked_by": [],
|
||||
"blocks": [],
|
||||
"scope": {
|
||||
"new_files": [
|
||||
"src/ai_client.py (mock provider _send_mock added — not a new file; in-place edit)",
|
||||
"tests/test_directive_structure.py (consolidation of the 7 scavenge files)",
|
||||
"tests/fixtures/mock_controller.py or conftest.py fixture (consolidation of the boilerplate patch block)",
|
||||
"docs/reports/TRACK_COMPLETION_test_suite_cleanup_gemini_cli_removal_20260705.md"
|
||||
],
|
||||
"modified_files": [
|
||||
"src/ai_client.py (gemini_cli removal + mock provider + dispatch branches)",
|
||||
"src/app_controller.py (gemini_cli removal + Metadata in-memory state migration)",
|
||||
"src/gui_2.py (gemini_cli panel removal)",
|
||||
"src/project_manager.py (gemini_cli default config removal)",
|
||||
"src/api_hooks.py (gemini_cli auto-start simplification)",
|
||||
"src/mcp_client.py (38 str wrappers deleted; dispatch() flipped to _result)",
|
||||
"src/aggregate.py (list[Metadata] -> list[FileItem])",
|
||||
"src/personas.py, src/workspace_manager.py, src/orchestrator_pm.py (scattered Metadata field triage)",
|
||||
"src/openai_schemas.py (to_legacy_dict deleted)",
|
||||
"tests/ (~45-60 files deleted/consolidated/migrated)",
|
||||
"docs/guide_ai_client.md, guide_architecture.md, guide_simulations.md, guide_models.md, guide_context_aggregation.md, guide_tools.md, Readme.md",
|
||||
"conductor/tech-stack.md, product.md, product-guidelines.md, workflow.md, code_styleguides/error_handling.md"
|
||||
],
|
||||
"deleted_files": [
|
||||
"src/gemini_cli_adapter.py",
|
||||
"tests/test_gemini_cli_adapter.py",
|
||||
"tests/test_gemini_cli_adapter_parity.py",
|
||||
"tests/test_gemini_cli_integration.py",
|
||||
"tests/test_gemini_cli_parity_regression.py",
|
||||
"tests/test_gemini_cli_edge_cases.py",
|
||||
"tests/test_mock_gemini_cli.py",
|
||||
"tests/test_ai_client_cli.py",
|
||||
"tests/test_generate_chronology.py",
|
||||
"tests/test_chronology_quality_gate.py",
|
||||
"tests/test_scavenge_batch_1.py through test_scavenge_batch_5.py",
|
||||
"tests/test_scavenge_directives_lift.py",
|
||||
"tests/test_scavenge_superpowers.py",
|
||||
"tests/test_ai_client_list_models.py (if the only test is the gemini_cli one)"
|
||||
]
|
||||
},
|
||||
"estimated_effort": {
|
||||
"method": "scope (per workflow.md Tier 1 Track Initialization Rules. NO day estimates.)",
|
||||
"phase_1": "11 tasks: gemini_cli removal (src + tests + docs) + mock provider + 9 sim test rewrites + checkpoint",
|
||||
"phase_2": "9 tasks: chronology test deletion + scavenge consolidation + deprecated-module review + phase-named consolidation + shim migration + mock_controller fixture + fix-not-skip + gui_2_result audit + checkpoint",
|
||||
"phase_3": "11 tasks: MCP dispatch flip + app_controller state migration + aggregate.py FileItem + scattered Metadata triage + dead code deletion + test fixture migration + docs + audits + batch + completion report + user verification + chronology row"
|
||||
},
|
||||
"verification_criteria": [
|
||||
"VC1: src/gemini_cli_adapter.py does not exist; grep -r 'gemini_cli' src/ returns only meta-tooling env-var references (or nothing)",
|
||||
"VC2: PROVIDERS in src/ai_client.py has 7 entries (no gemini_cli)",
|
||||
"VC3: tests/test_generate_chronology.py + tests/test_chronology_quality_gate.py do not exist",
|
||||
"VC4: the 7 test_scavenge_*.py files do not exist; tests/test_directive_structure.py exists and checks the general invariant",
|
||||
"VC5: grep -r 'from src.models import' tests/ returns only the 2 self-test files (test_models_no_top_level_*.py)",
|
||||
"VC6: grep -r 'list\\[Metadata\\]' src/app_controller.py returns nothing",
|
||||
"VC7: src/mcp_client.py has no str-returning wrappers (the 38 are deleted; dispatch() returns Result)",
|
||||
"VC8: src/aggregate.py uses list[FileItem], not list[Metadata]",
|
||||
"VC9: the 3 fix-not-skip tests are fixed (no @pytest.mark.skip for the Gemini 503 reason)",
|
||||
"VC10: the 4 audit scripts pass",
|
||||
"VC11: the full test suite batch run passes (or pre-existing failures documented)",
|
||||
"VC12: src/openai_schemas.py:108 to_legacy_dict() is deleted"
|
||||
],
|
||||
"regressions_and_pre_existing_failures": [],
|
||||
"pre_existing_failures_remaining": [],
|
||||
"deferred_to_followup_tracks": [
|
||||
{
|
||||
"title": "Meta-tooling GEMINI_CLI_HOOK_CONTEXT env var purge",
|
||||
"description": "The GEMINI_CLI_HOOK_CONTEXT env var + scripts/cli_tool_bridge.py + scripts/mma_exec.py + docs/guide_meta_boundary.md are meta-tooling (external agent bridge), NOT the provider. If the user wants to purge the naming, that's a separate track.",
|
||||
"track_status": "not yet initialized; depends on user decision"
|
||||
},
|
||||
{
|
||||
"title": "Full mock provider implementation",
|
||||
"description": "This track introduces just enough of a mock provider to keep the 9 sim tests working. A full mock-provider implementation (configurable responses, error injection, latency simulation) is a future track.",
|
||||
"track_status": "future; depends on user demand"
|
||||
},
|
||||
{
|
||||
"title": "RAG return type follow-up (typed_rag_return_type_followup)",
|
||||
"description": "From the archive review: rag_engine.search() returns List[Dict[str, Any]]; RAGChunk exists but consumers read dict keys. Adjacent to GAP-C2 but not bundled (RAG boundary is its own scope).",
|
||||
"track_status": "future; from ARCHIVE_REVIEW_20260705.md item #1"
|
||||
},
|
||||
{
|
||||
"title": "Typed tool builders follow-up (typed_tool_builders_followup)",
|
||||
"description": "From the archive review: per-vendor tool builders construct wire-format dicts directly; ToolDefinition exists but isn't used. Adjacent to GAP-C2 but not bundled.",
|
||||
"track_status": "future; from ARCHIVE_REVIEW_20260705.md item #2"
|
||||
}
|
||||
],
|
||||
"risk_register": [
|
||||
{
|
||||
"id": "R1",
|
||||
"description": "The 9 sim test rewrites (gemini_cli -> mock) break the live_gui fixture's session-scoped state",
|
||||
"likelihood": "medium",
|
||||
"impact": "the batch run fails on the sim tests",
|
||||
"mitigation": "the mock provider uses the same mock_gemini_cli.py script; the only change is the provider name. Test in isolation first, then in the full batch per the Isolated-Pass Verification Fallacy rule."
|
||||
},
|
||||
{
|
||||
"id": "R2",
|
||||
"description": "The MCP dispatch flip (Task 3.1) breaks 22 consumer call sites",
|
||||
"likelihood": "medium",
|
||||
"impact": "the batch run fails on aggregate.py/gui_2.py/app_controller.py tests",
|
||||
"mitigation": "do it in sub-commits (aggregate.py first, then gui_2.py, then delete the wrappers); test after each sub-commit"
|
||||
},
|
||||
{
|
||||
"id": "R3",
|
||||
"description": "The app_controller.py state migration (Task 3.2) breaks tests that construct Metadata({...}) fixtures",
|
||||
"likelihood": "high",
|
||||
"impact": "the tests fail at fixture construction",
|
||||
"mitigation": "Task 3.6 migrates the test fixtures; do it immediately after Task 3.2, not at the end"
|
||||
},
|
||||
{
|
||||
"id": "R4",
|
||||
"description": "test_gui_2_result.py (120KB) audit reveals it's all current behavior — no deletion possible",
|
||||
"likelihood": "low",
|
||||
"impact": "the file stays large; Front B's downsizing target is reduced",
|
||||
"mitigation": "the audit is the task; even if no deletion is possible, the split into per-feature files is still a win for navigability"
|
||||
}
|
||||
],
|
||||
"research_artifacts": {
|
||||
"gemini_cli_audit": "The explore-agent inventory of all gemini_cli references (file:line, grouped by file) — attached as track research.",
|
||||
"test_suite_audit": "The explore-agent cruft map (410 files, 2,133 tests, top 20 largest, 7 skips, 74 Metadata refs, 35 src.models importers, 100+ mock.patch sites, duplicates) — attached as track research.",
|
||||
"legacy_api_audit": "The explore-agent legacy-debt audit (send() current signature, the 38 str wrappers, the 27 src.models importers, the 69 dict[str, Any] sites, the 380 Metadata refs across 22 files, the dead code) — attached as track research."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
# Plan: Test Suite Cleanup + Gemini CLI Adapter Removal + Metadata-Type Reduction
|
||||
|
||||
Track: `test_suite_cleanup_gemini_cli_removal_20260705`
|
||||
Branch: master
|
||||
Spec: `conductor/tracks/test_suite_cleanup_gemini_cli_removal_20260705/spec.md`
|
||||
|
||||
3 fronts, 3 phases. Front A (Gemini CLI removal) first because it deletes test files + rewrites 9 more — the entry point for Front B (test cleanup). Front C (metadata reduction) last because it's the largest production-code change + the test cleanup needs to reflect the typed-dataclass migration.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Front A — Gemini CLI Adapter Removal
|
||||
|
||||
Focus: delete the adapter module + the provider registration + the GUI panel + the test files. Introduce the `mock` provider for the 9 sim tests that used `gemini_cli` + `mock_gemini_cli.py`.
|
||||
|
||||
- [ ] **Task 1.1: Delete `src/gemini_cli_adapter.py`**
|
||||
|
||||
WHERE: `src/gemini_cli_adapter.py` (193 lines, entire file).
|
||||
WHAT: `git rm src/gemini_cli_adapter.py`.
|
||||
VERIFY: `Test-Path src/gemini_cli_adapter.py` returns False.
|
||||
|
||||
- [ ] **Task 1.2: Edit `src/ai_client.py` — remove the import, PROVIDERS entry, module state, 3 functions, 8 dispatch branches**
|
||||
|
||||
WHERE: `src/ai_client.py` lines 49, 62, 164, 1727-1735, 2130-2241, 1857-1877, 556-561, 629, 914, 3302, 3306, 3394-3398, 3505-3509, 3556-3559.
|
||||
WHAT: Per the audit inventory (GAP-A2). Carefully distinguish `_gemini_cli_adapter` (REMOVE) from `_gemini_client` / `_ensure_gemini_client` (KEEP — direct Gemini SDK).
|
||||
HOW: Use `manual-slop_py_update_definition` for the 3 function removals; `manual-slop_edit_file` for the dispatch branches + import + PROVIDERS + module state.
|
||||
VERIFY: `python -c "from src.ai_client import PROVIDERS; print(PROVIDERS)"` prints 7 entries (no `gemini_cli`).
|
||||
|
||||
- [ ] **Task 1.3: Edit `src/app_controller.py` — remove the ~11 gemini_cli sites**
|
||||
|
||||
WHERE: `src/app_controller.py` lines 574-575, 1084, 1124, 1316, 1836-1840, 2022-2023, 2725-2729, 2932, 3215, 4124.
|
||||
WHAT: Per GAP-A3 — remove `ui_gemini_cli_path` state field, settable/gettable map entries, `_update_gcli_adapter()` method, project load/save, init.
|
||||
VERIFY: `grep "gemini_cli" src/app_controller.py` returns nothing.
|
||||
|
||||
- [ ] **Task 1.4: Edit `src/gui_2.py` — remove the 2 gemini_cli blocks**
|
||||
|
||||
WHERE: `src/gui_2.py` lines 2940-2947 (ASCII comment) + 3008-3025 (provider panel block).
|
||||
WHAT: Delete both blocks.
|
||||
VERIFY: `grep "gemini_cli" src/gui_2.py` returns nothing.
|
||||
|
||||
- [ ] **Task 1.5: Edit `src/project_manager.py:126` + `src/api_hooks.py:88, 941-942`**
|
||||
|
||||
WHERE: `src/project_manager.py:126` (delete the default config entry) + `src/api_hooks.py:88` (delete the docstring line) + `src/api_hooks.py:941-942` (simplify the HookServer auto-start — the `is_gemini_cli` special case becomes dead).
|
||||
VERIFY: `grep "gemini_cli" src/project_manager.py src/api_hooks.py` returns nothing.
|
||||
|
||||
- [ ] **Task 1.6: Delete the 7 gemini_cli test files**
|
||||
|
||||
WHERE: `tests/test_gemini_cli_adapter.py`, `tests/test_gemini_cli_adapter_parity.py`, `tests/test_gemini_cli_integration.py`, `tests/test_gemini_cli_parity_regression.py`, `tests/test_gemini_cli_edge_cases.py`, `tests/test_mock_gemini_cli.py`, `tests/test_ai_client_cli.py`.
|
||||
WHAT: `git rm` all 7.
|
||||
VERIFY: `Test-Path` returns False for all 7.
|
||||
|
||||
- [ ] **Task 1.7: Introduce the `mock` provider in `src/ai_client.py`**
|
||||
|
||||
WHERE: `src/ai_client.py` — add a `_send_mock()` function + the `"mock"` entry in PROVIDERS (replacing `"gemini_cli"`) + the dispatch branch.
|
||||
WHAT: The `mock` provider routes to `tests/mock_gemini_cli.py` (the same script the sim tests already use). It returns `Result[str]` like every other provider. It reads the binary path from the same `gcli_path` settable field (renamed to `mock_cli_path` if the user prefers, but keeping `gcli_path` minimizes test churn).
|
||||
HOW: Mirror the `_send_gemini_cli()` structure but name it `_send_mock()`. The provider name is `"mock"`.
|
||||
VERIFY: `python -c "from src.ai_client import PROVIDERS; print('mock' in PROVIDERS)"` prints True.
|
||||
|
||||
- [ ] **Task 1.8: Rewrite the 9 sim test files to use `mock` instead of `gemini_cli`**
|
||||
|
||||
WHERE: `tests/test_extended_sims.py`, `tests/test_live_workflow.py`, `tests/test_mma_concurrent_tracks_sim.py`, `tests/test_mma_concurrent_tracks_stress_sim.py`, `tests/test_mma_step_mode_sim.py`, `tests/test_rag_phase4_final_verify.py`, `tests/test_rag_phase4_stress.py`, `tests/test_sim_ai_settings.py`, `tests/test_process_pending_gui_tasks.py`.
|
||||
WHAT: Replace `set_value('current_provider', 'gemini_cli')` with `set_value('current_provider', 'mock')`. Replace `gcli_path` references if renamed. Keep `mock_gemini_cli.py` + `mock_gcli.bat` (they're now the mock provider's backend).
|
||||
VERIFY: `grep "gemini_cli" tests/test_extended_sims.py ...` returns nothing across all 9 files.
|
||||
|
||||
- [ ] **Task 1.9: Minor edits in the 6+ gemini_cli-reference test files**
|
||||
|
||||
WHERE: `test_providers_source_of_truth.py` (remove from EXPECTED_PROVIDERS), `test_provider_curation.py` (remove from expected_providers), `test_ai_client_tool_loop_send_func.py` (update comment), `test_mma_tier_usage_reset_fix.py` (remove `ctrl.ui_gemini_cli_path = ""`), `test_rag_integration.py` (remove `app.ui_gemini_cli_path = "gemini"`), `test_ai_loop_regressions_20260614.py` (remove the 3 `_update_gcli_adapter` monkeypatches), `test_live_gui_integration_v2.py` (remove the 2 `_update_gcli_adapter` patches), `test_lazymodule_filedialog_fallback.py` (update comment), `test_discussion_compression.py` (delete the `test_discussion_compression_gemini_cli` test function), `test_ai_client_list_models.py` (delete the `test_list_models_gemini_cli` test function; if it's the only test, delete the file), `test_mock_concurrent_mma.py` (update comments).
|
||||
VERIFY: `grep -r "gemini_cli" tests/ | grep -v mock_gemini_cli.py | grep -v test_mock` returns nothing (the mock script + its self-test keep the name; everything else is gone).
|
||||
|
||||
- [ ] **Task 1.10: Update the docs + conductor docs**
|
||||
|
||||
WHERE: 7 guide files (`guide_ai_client.md`, `guide_architecture.md`, `guide_simulations.md`, `guide_models.md`, `guide_context_aggregation.md`, `guide_tools.md`, `Readme.md`) + 5 conductor docs (`tech-stack.md`, `product.md`, `product-guidelines.md`, `workflow.md`, `code_styleguides/error_handling.md`).
|
||||
WHAT: Per GAP-A11 — remove `gemini_cli` from provider lists, delete the Gemini CLI subsections, update the provider count from 8 to 7. Update `guide_simulations.md` to reference the `mock` provider instead of `gemini_cli`.
|
||||
VERIFY: `grep -r "gemini_cli" docs/guide_*.md docs/Readme.md conductor/tech-stack.md conductor/product.md conductor/workflow.md` returns only the meta-tooling references (or nothing if the user purged those).
|
||||
|
||||
- [ ] **Task 1.11: Phase 1 checkpoint + batch run**
|
||||
|
||||
WHAT: Run the affected test files in batch: `uv run python scripts/run_tests_batched.py --filter test_extended_sims --filter test_live_workflow --filter test_mma_concurrent --filter test_rag_phase4 --filter test_sim_ai_settings --filter test_process_pending --filter test_providers_source --filter test_provider_curation`.
|
||||
VERIFY: batch green. Commit the Phase 1 checkpoint.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Front B — Test Suite Cleanup
|
||||
|
||||
Focus: delete the guaranteed-broken cruft, consolidate the one-time-verification cruft, review the phase-named one-offs, migrate the legacy shim importers, fix the fix-not-skip candidates.
|
||||
|
||||
- [ ] **Task 2.1: Delete the 2 guaranteed-broken chronology test files**
|
||||
|
||||
WHERE: `tests/test_generate_chronology.py` (205 lines, 20 tests) + `tests/test_chronology_quality_gate.py` (76 lines, 5 tests).
|
||||
WHAT: `git rm` both. They import from deleted `scripts.audit.*` modules.
|
||||
VERIFY: `Test-Path` returns False for both.
|
||||
|
||||
- [ ] **Task 2.2: Consolidate the 7 `test_scavenge_*.py` files into one `test_directive_structure.py`**
|
||||
|
||||
WHERE: `tests/test_scavenge_batch_1.py` through `test_scavenge_batch_5.py` + `test_scavenge_directives_lift.py` + `test_scavenge_superpowers.py`.
|
||||
WHAT: Delete the 7 files. Write `tests/test_directive_structure.py` that checks the general invariant: every directive in `conductor/directives/current_baseline.md` has a `v1.md` + `meta.md` in its directory. This is the ongoing behavioral contract; the per-batch lists were one-time verifications.
|
||||
VERIFY: `Test-Path tests/test_directive_structure.py` returns True; the 7 scavenge files return False.
|
||||
|
||||
- [ ] **Task 2.3: Review + delete or rewrite the deprecated-module test files**
|
||||
|
||||
WHERE: `tests/test_mma_skeleton.py` (imports from deprecated `scripts/mma_exec`), `tests/test_arch_boundary_phase1.py` (tests deprecated `scripts/mma_exec.py` / `claude_mma_exec.py` hardcoded paths).
|
||||
WHAT: Review each. If the assertions are still relevant, rewrite to use the OpenCode Task tool (the replacement per workflow.md). If not, delete.
|
||||
VERIFY: per-file review note in the commit message.
|
||||
|
||||
- [ ] **Task 2.4: Review + consolidate the ~15 `test_*_phase*.py` files**
|
||||
|
||||
WHERE: `test_arch_boundary_phase1/2/3.py`, `test_context_composition_phase3/4/6.py`, `test_gui_phase3/4.py`, `test_mma_agent_focus_phase1/3.py`, `test_code_path_audit_phase78/89.py`, `test_metadata_promotion_phase1.py`, `test_rag_phase4_final_verify.py`, `test_rag_phase4_stress.py`.
|
||||
WHAT: Review each. Merge still-relevant assertions into the general test file (e.g., `test_code_path_audit.py`). Delete the trivially-green + redundant ones.
|
||||
VERIFY: per-file review note in the commit message; the general files still pass.
|
||||
|
||||
- [ ] **Task 2.5: Migrate the 27 `src.models` test importers to direct subsystem imports**
|
||||
|
||||
WHERE: 27 test files (per GAP-B5). 3 use `Metadata` (→ `from src.mma import TrackMetadata`). 3 use `PROVIDERS` (→ `from src.ai_client import PROVIDERS`). 20 use `from src import models` bare (→ direct subsystem imports). 2 self-test files remain.
|
||||
WHAT: Per-file migration. Each is a small edit (change the import line + update the `models.X` references to `X`).
|
||||
VERIFY: `grep -r "from src.models import" tests/ | grep -v test_models_no_top_level` returns nothing.
|
||||
|
||||
- [ ] **Task 2.6: Extract the shared `mock_controller` fixture from the ~8 boilerplate-patch files**
|
||||
|
||||
WHERE: `test_app_controller_result.py`, `test_discussion_takes_gui.py`, `test_gui_events_v2.py`, `test_gui_synthesis.py`, `test_auto_slices.py`, `test_arch_boundary_phase2.py`, `test_api_hook_extensions.py`, `test_api_events.py` (the 8 files with the `patch('...load_config') + patch('..._init_ai_and_hooks') + patch('..._fetch_models')` block).
|
||||
WHAT: Extract the boilerplate into a `tests/conftest.py` fixture `mock_controller` (or a `tests/fixtures/mock_controller.py`). Each test file drops the boilerplate + uses the fixture.
|
||||
VERIFY: the boilerplate block appears in 0 test files (only in the fixture).
|
||||
|
||||
- [ ] **Task 2.7: Fix the 3 fix-not-skip candidates (mock the Gemini 503)**
|
||||
|
||||
WHERE: `tests/test_context_composition_phase6.py` (3 skips) + `tests/test_aggregate_flags.py` (1 skip) — all share the root cause: live Gemini 503 in `summarize.summarise_file`.
|
||||
WHAT: Mock the Gemini call (patch `summarize.summarise_file` or the underlying `ai_client.send`) to return a canned response. Remove the `@pytest.mark.skip` markers.
|
||||
VERIFY: `grep -r "Gemini 503" tests/` returns nothing.
|
||||
|
||||
- [ ] **Task 2.8: Audit + split `test_gui_2_result.py` (120KB, 2,329 lines, 101 tests)**
|
||||
|
||||
WHERE: `tests/test_gui_2_result.py` — 9.4% of the suite's line count in one file.
|
||||
WHAT: Audit whether it's testing current behavior or accumulated GUI regression snapshots. Split into per-feature files (e.g., `test_gui_2_result_rendering.py`, `test_gui_2_result_events.py`, `test_gui_2_result_state.py`). Delete the obsolete snapshots.
|
||||
VERIFY: the resulting files are each <500 lines; the behavioral assertions still pass.
|
||||
|
||||
- [ ] **Task 2.9: Phase 2 checkpoint + batch run**
|
||||
|
||||
WHAT: Run the full suite batch (per the Isolated-Pass Verification Fallacy — batch green is the only verification that matters): `uv run python scripts/run_tests_batched.py`.
|
||||
VERIFY: batch green (or pre-existing failures documented). Commit the Phase 2 checkpoint.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Front C — Metadata-Type Reduction
|
||||
|
||||
Focus: flip the MCP dispatch inversion, migrate `app_controller.py` in-memory state to typed dataclasses, fix `aggregate.py` FileItem slippage, delete dead code.
|
||||
|
||||
- [ ] **Task 3.1: Flip the MCP dispatch inversion (38 str wrappers → 39 _result variants)**
|
||||
|
||||
WHERE: `src/mcp_client.py` — the 38 str-returning wrappers (lines ~291-560) + the `dispatch()` function (line 1869) + `async_dispatch()` + 22 external call sites in `aggregate.py` (×12), `gui_2.py` (×9), `app_controller.py` (×1).
|
||||
WHAT: Update `dispatch()` + `async_dispatch()` to call the `_result` variants directly + return `Result`. Update the 22 consumer call sites to consume `Result` (check `.ok`, use `.data`, handle `.errors`). Delete the 38 str wrappers.
|
||||
HOW: This is the single largest production-code change in the track. Do it in sub-commits: (a) flip `dispatch()` + the `aggregate.py` call sites; (b) flip `async_dispatch()` + the `gui_2.py` call sites; (c) delete the str wrappers.
|
||||
VERIFY: `grep -r "def search_files\|def read_file\|def write_file" src/mcp_client.py` returns only the `_result` variants; the str wrappers are gone. `grep "; ".join(e.ui_message()" src/mcp_client.py` returns nothing.
|
||||
|
||||
- [ ] **Task 3.2: Migrate `app_controller.py` in-memory state to typed dataclasses**
|
||||
|
||||
WHERE: `src/app_controller.py` — the ~40 `Metadata`-typed in-memory state collections (GAP-C2): `_pending_gui_tasks`, `_tool_log`, `_tool_stats`, `_cached_cache_stats`, `_token_history`, `_comms_log`, `_pending_comms`, `_pending_tool_calls`, `_pending_history_adds`, `_ask_tool_data`, `_pending_mma_approvals`, `_pending_mma_spawns`, `_token_stats`, `vendor_quota`. Plus `Metadata()` construction at lines 2774, 2778, 3443.
|
||||
WHAT: Replace each `list[Metadata]` / `Dict[str, Metadata]` / `Metadata = {}` with the corresponding typed per-aggregate dataclass from `type_aliases.py` (`CommsLogEntry`, `HistoryMessage`, `ToolCall`, etc.). If a needed dataclass doesn't exist, add it to `type_aliases.py` (NOT a new `src/<thing>.py` per AGENTS.md).
|
||||
HOW: Per-collection migration in sub-commits. Each collection is its own commit (e.g., "refactor(app_controller): _comms_log: list[Metadata] → list[CommsLogEntry]").
|
||||
VERIFY: `grep -r "list\[Metadata\]" src/app_controller.py` returns nothing. `grep -r "Metadata()" src/app_controller.py` returns nothing.
|
||||
|
||||
- [ ] **Task 3.3: Fix `aggregate.py` FileItem slippage**
|
||||
|
||||
WHERE: `src/aggregate.py` — `file_items: list[Metadata]` throughout (`build_file_items`, `_build_files_section_from_items`, `build_markdown_from_items`, `build_tier3_context`, `build_markdown`, `run`) + `NIL_METADATA: Metadata = {}` sentinel at line 50.
|
||||
WHAT: Change to `list[FileItem]` (the `FileItem` dataclass exists in `src/project_files.py`, aliased in `type_aliases.py:149`). Replace `NIL_METADATA: Metadata = {}` with `NIL_FILE_ITEMS: tuple[FileItem, ...] = ()` (or similar typed empty sentinel).
|
||||
VERIFY: `grep "list\[Metadata\]" src/aggregate.py` returns nothing. `grep "NIL_METADATA" src/aggregate.py` returns nothing.
|
||||
|
||||
- [ ] **Task 3.4: Triage the scattered non-boundary `Metadata` fields**
|
||||
|
||||
WHERE: `src/personas.py:22` (`preferred_models: list[Metadata]`), `src/workspace_manager.py:16` (`panel_states: Metadata`), `src/orchestrator_pm.py:57` (`generate_tracks(project_config: Metadata) -> list[Metadata]`).
|
||||
WHAT: Per-site triage. `preferred_models` → `list[ModelEntry]` (define `ModelEntry` in `type_aliases.py` if needed). `panel_states` → a typed panel-state dataclass. `generate_tracks` → typed config + track-entry dataclasses.
|
||||
VERIFY: per-site commit message documents the chosen type.
|
||||
|
||||
- [ ] **Task 3.5: Delete the dead/deprecated code**
|
||||
|
||||
WHERE: `src/openai_schemas.py:108` (`to_legacy_dict()` — zero callers) + `src/app_controller.py:4973` (`_push_mma_state_update` — DEPRECATED; verify no callers first via `grep -r "_push_mma_state_update[^_]" src/ tests/`).
|
||||
WHAT: Delete both.
|
||||
VERIFY: `grep "to_legacy_dict" src/openai_schemas.py` returns nothing. `grep "_push_mma_state_update[^_]" src/ tests/` returns nothing.
|
||||
|
||||
- [ ] **Task 3.6: Migrate the test fixtures that construct `Metadata({...})` to the new typed dataclasses**
|
||||
|
||||
WHERE: any test file that constructs `Metadata({...})` for the collections migrated in Task 3.2.
|
||||
WHAT: Replace `Metadata({"path": ..., "content": ...})` with the corresponding typed dataclass constructor (`FileItem(path=..., content=...)`, `CommsLogEntry(...)`, etc.).
|
||||
VERIFY: the tests pass with the new constructors.
|
||||
|
||||
- [ ] **Task 3.7: Update the docs to reflect the Metadata reduction**
|
||||
|
||||
WHERE: `docs/guide_app_controller.md` (the in-memory state section), `docs/guide_mcp_client.md` (the dispatch surface), `docs/guide_models.md` (the Metadata boundary scope), `conductor/code_styleguides/type_aliases.md` (the new typed dataclasses).
|
||||
WHAT: Document the reduced Metadata scope (TOML/JSON boundary only) + the new typed in-memory state.
|
||||
VERIFY: the docs reflect the post-migration state.
|
||||
|
||||
- [ ] **Task 3.8: Run the 4 audit scripts + the full test suite batch**
|
||||
|
||||
WHAT: `uv run python scripts/audit_main_thread_imports.py`, `uv run python scripts/audit_no_models_config_io.py`, `uv run python scripts/audit_weak_types.py --strict`, `uv run python scripts/audit_exception_handling.py --strict`. Then `uv run python scripts/run_tests_batched.py`.
|
||||
VERIFY: all 4 audits pass; the batch is green (or pre-existing failures documented).
|
||||
|
||||
- [ ] **Task 3.9: Phase 3 checkpoint + TRACK_COMPLETION report**
|
||||
|
||||
WHERE: `docs/reports/TRACK_COMPLETION_test_suite_cleanup_gemini_cli_removal_20260705.md`.
|
||||
WHAT: Per the `tier2_autonomous_sandbox_20260616` precedent — what was done, files deleted/modified, test counts before/after, audit results, deferred items.
|
||||
VERIFY: report committed + `state.toml` updated to `status = "completed"`.
|
||||
|
||||
- [ ] **Task 3.10: Conductor — User Manual Verification (Protocol in workflow.md)**
|
||||
|
||||
Present the verification results to the user. PAUSE for user confirmation before marking the track complete.
|
||||
|
||||
- [ ] **Task 3.11: Add the chronology row + archive the track**
|
||||
|
||||
WHERE: `conductor/chronology.md` (add a row at the top) + `git mv conductor/tracks/test_suite_cleanup_gemini_cli_removal_20260705/ conductor/archive/`.
|
||||
WHAT: Per the manual chronology maintenance protocol (no scripts).
|
||||
@@ -0,0 +1,164 @@
|
||||
# Track Specification: Test Suite Cleanup + Gemini CLI Adapter Removal + Metadata-Type Reduction
|
||||
|
||||
## Overview
|
||||
|
||||
A three-front cleanup track that downsizes the test suite without losing testing integrity, removes the now-graveyarded Gemini CLI adapter implementation from the codebase, and continues the metadata-type reduction beyond TOML boundaries. The three fronts are tightly coupled: removing the Gemini CLI provider deletes 7 test files + rewrites 9 more, which is the natural entry point for the broader test-suite pruning; the metadata-type reduction is the unfinished migration work the test cleanup needs to reflect.
|
||||
|
||||
**Why these three are bundled:** the user explicitly framed them as one effort — "help me get this test suite downsized without losing testing integrity or coverage" + "the gemini cli adapter impl needs to be removed" + "reduction of metadata type usage beyond toml boundaries." The Gemini CLI removal alone touches ~30 files; the test-suite pruning touches ~45-60 files; the metadata-type reduction touches `app_controller.py`, `aggregate.py`, and ~27 test files. Doing them in one track avoids three rounds of overlapping churn on `tests/` and `src/ai_client.py`.
|
||||
|
||||
## Current State Audit (as of master `0908f8fa`)
|
||||
|
||||
### Already Implemented (DO NOT re-implement)
|
||||
|
||||
- **The Result[T] migration is complete at the public API.** `ai_client.send() -> Result[str]` is canonical; all 9 `_send_<vendor>` helpers return `Result[str]`; all external callers consume `result.ok`/`result.data`/`result.errors` correctly. (Verified by audit #3.)
|
||||
- **`Optional[T]` return types are fully banned in `src/mcp_client.py`, `src/ai_client.py`, `src/rag_engine.py`.** Zero violations across all 67 `src/` files. The ban holds.
|
||||
- **`src/` no longer imports from `src/models.py`** — the production-side migration to per-system files (`src/mma.py`, `src/type_aliases.py`, `src/mcp_tool_specs.py`, `src/result_types.py`) is complete per `module_taxonomy_refactor_20260627`.
|
||||
- **`scripts/audit/generate_chronology.py` + `chronology_quality_gate.py` were deleted 2026-07-05** (this session, commit `4c9fc99c`). The chronology is now manually maintained.
|
||||
- **The `scripts/video_analysis/` pipeline** is the standalone-tooling precedent (unrelated to this track but referenced as the pattern for `scripts/twitter_threads/` which is a separate in-flight track).
|
||||
|
||||
### Gaps to Fill (This Track's Scope)
|
||||
|
||||
**Front A — Gemini CLI Adapter Removal (8 files to delete, ~30 files to edit):**
|
||||
|
||||
- **GAP-A1:** `src/gemini_cli_adapter.py` (193 lines) — the standalone adapter module. Delete entirely.
|
||||
- **GAP-A2:** `src/ai_client.py` — 3 functions to delete (`_list_gemini_cli_models`, `_send_gemini_cli`, `_send_cli_round_result`) + ~8 dispatch branches to remove (lines 556, 629, 914, 3302, 3306, 3394, 3505, 3556) + the import on line 49 + the `PROVIDERS` entry on line 62 + the module state on line 164. **Carefully distinguish `_gemini_cli_adapter` (REMOVE) from `_gemini_client` / `_ensure_gemini_client` (KEEP — that's the direct Gemini SDK provider).**
|
||||
- **GAP-A3:** `src/app_controller.py` — ~11 sites to remove (state field `ui_gemini_cli_path`, settable/gettable maps, `_update_gcli_adapter()` method, project load/save, init).
|
||||
- **GAP-A4:** `src/gui_2.py` — 2 blocks to remove (ASCII layout comment lines 2940-2947 + the provider-panel block lines 3008-3025).
|
||||
- **GAP-A5:** `src/project_manager.py:126` — delete the `"gemini_cli": {"binary_path": "gemini"}` default.
|
||||
- **GAP-A6:** `src/api_hooks.py:88, 941-942` — delete the docstring line + simplify the HookServer auto-start condition (the `is_gemini_cli` special case becomes dead).
|
||||
- **GAP-A7:** 7 test files to DELETE entirely: `test_gemini_cli_adapter.py`, `test_gemini_cli_adapter_parity.py`, `test_gemini_cli_integration.py`, `test_gemini_cli_parity_regression.py`, `test_gemini_cli_edge_cases.py`, `test_mock_gemini_cli.py`, `test_ai_client_cli.py`.
|
||||
- **GAP-A8:** `tests/mock_gemini_cli.py` + `tests/mock_gcli.bat` — **DO NOT DELETE.** Repurpose: 9 live_gui simulation tests use `mock_gemini_cli.py` as a generic mock LLM provider. The track introduces a `mock` provider in `ai_client.py` (or repurposes the existing `"mock"` model-name special case at line 558) that routes to this same script. The 9 sim tests switch from `set_value('current_provider', 'gemini_cli')` to `set_value('current_provider', 'mock')`. This preserves the test infrastructure.
|
||||
- **GAP-A9:** 9 sim test files to REWRITE (the mock-provider switch): `test_extended_sims.py`, `test_live_workflow.py`, `test_mma_concurrent_tracks_sim.py`, `test_mma_concurrent_tracks_stress_sim.py`, `test_mma_step_mode_sim.py`, `test_rag_phase4_final_verify.py`, `test_rag_phase4_stress.py`, `test_sim_ai_settings.py`, `test_process_pending_gui_tasks.py`.
|
||||
- **GAP-A10:** 6 test files with minor edits (remove `gemini_cli` from provider lists, remove monkeypatches/patches): `test_providers_source_of_truth.py`, `test_provider_curation.py`, `test_ai_client_tool_loop_send_func.py`, `test_mma_tier_usage_reset_fix.py`, `test_rag_integration.py`, `test_ai_loop_regressions_20260614.py`, `test_live_gui_integration_v2.py`, `test_lazymodule_filedialog_fallback.py`, `test_discussion_compression.py`, `test_ai_client_list_models.py` (delete the single test function; if it's the only one, delete the file).
|
||||
- **GAP-A11:** Docs: 7 guide files + Readme to update (`guide_ai_client.md`, `guide_architecture.md`, `guide_simulations.md`, `guide_models.md`, `guide_context_aggregation.md`, `guide_tools.md`, `Readme.md`). Conductor docs: 5 files (`tech-stack.md`, `product.md`, `product-guidelines.md`, `workflow.md`, `code_styleguides/error_handling.md`).
|
||||
- **GAP-A12 (DECISION POINT — out of scope unless user confirms):** `GEMINI_CLI_HOOK_CONTEXT` env var + `scripts/cli_tool_bridge.py` + `scripts/mma_exec.py` + `docs/guide_meta_boundary.md` — these are **meta-tooling** references (the external AI agent bridge), NOT the provider. Recommend: leave as-is. If the user wants to purge the meta-tooling naming too, that's a separate follow-up track.
|
||||
|
||||
**Front B — Test Suite Cleanup (Tier 1-4 cruft, ~45-60 files, ~300-400 tests):**
|
||||
|
||||
- **GAP-B1 (Tier 1 — guaranteed-broken cruft, DELETE):** `tests/test_generate_chronology.py` (205 lines, 20 tests) + `tests/test_chronology_quality_gate.py` (76 lines, 5 tests). Both import from `scripts.audit.generate_chronology` + `chronology_quality_gate` which were DELETED 2026-07-05. These tests are guaranteed `ImportError` at collection time.
|
||||
- **GAP-B2 (Tier 2 — one-time verification cruft, CONSOLIDATE):** 7 `test_scavenge_*.py` files (~44KB, ~40 tests) verify that the 2026-07-02/03 directive-lift happened (specific directive names exist with v1.md/meta.md). Once the lift shipped, these are permanently-green tautologies with zero ongoing behavioral value. Consolidate into one `test_directive_structure.py` that checks the general invariant (all directives in `current_baseline.md` have v1.md + meta.md), not per-batch lists.
|
||||
- **GAP-B3 (Tier 3 — deprecated-module references, REVIEW):** `test_mma_skeleton.py` imports from `scripts/mma_exec` (DEPRECATED). `test_arch_boundary_phase1.py` tests hardcoded paths in `scripts/mma_exec.py` / `scripts/claude_mma_exec.py` (DEPRECATED per workflow.md). Review + delete or rewrite.
|
||||
- **GAP-B4 (Tier 4 — phase-named one-off tests, REVIEW + CONSOLIDATE):** ~15 `test_*_phase*.py` files pin track-phase outputs. Many are now redundant with the general test file (e.g., `test_code_path_audit_phase78.py` + `test_code_path_audit_phase89.py` vs `test_code_path_audit.py`). Some are trivially green (e.g., `test_phase_3_final_verify.py` = 7 lines). Review each; merge the still-relevant assertions into the general file; delete the rest.
|
||||
- **GAP-B5 (Tier 5 — legacy `src.models` shim imports, MIGRATE):** 27 test files import from `src.models`. 3 use `Metadata` (→ `from src.mma import TrackMetadata`). 3 use `PROVIDERS` (→ `from src.ai_client import PROVIDERS`). 20 use `from src import models` bare (→ direct subsystem imports). 2 self-test files (`test_models_no_top_level_*.py`) remain.
|
||||
- **GAP-B6 (Tier 6 — heavy mock-patch boilerplate, CONSOLIDATE):** the `patch('src.app_controller.AppController.load_config'...) + patch('..._init_ai_and_hooks') + patch('..._fetch_models')` block repeats across ~8 test files as boilerplate. Extract a shared `mock_controller` fixture or migrate to `live_gui` where feasible.
|
||||
- **GAP-B7 (Tier 7 — fix-not-skip, FIX):** 3 skips in `test_context_composition_phase6.py` + `test_aggregate_flags.py` share one root cause (live Gemini 503 in `summarize.summarise_file`). Per project skip-marker policy, these should be fixed by mocking the Gemini call, not skipped.
|
||||
- **GAP-B8:** `test_gui_2_result.py` (120KB, 2,329 lines, 101 tests) — the single largest test file (9.4% of the suite's line count). Audit whether it's testing current behavior or accumulated GUI regression snapshots. If the latter, split into per-feature files + delete the obsolete snapshots.
|
||||
|
||||
**Front C — Metadata-Type Reduction Beyond TOML Boundaries:**
|
||||
|
||||
- **GAP-C1 (Layer 1 — the MCP tool dispatch inversion, 38 sites):** `src/mcp_client.py` has 38 legacy str-returning wrappers that remain the **actual public surface** — `dispatch()` (line 1869) and all 22 external call sites in `aggregate.py`/`gui_2.py`/`app_controller.py` call the str wrappers, NOT the 39 `_result` variants. The Result-migration created the new surface but never flipped the dispatch table or the consumers. **Fix:** update `dispatch()` + `async_dispatch()` + 22 consumer call sites to use the `_result` variants, then delete the 38 str wrappers.
|
||||
- **GAP-C2 (Layer 2 — `app_controller.py` in-memory state, 40 sites of 81 Metadata refs):** in-memory state collections typed as `list[Metadata]`/`Dict[str, Metadata]`/`Metadata = {}` — `_pending_gui_tasks`, `_tool_log`, `_tool_stats`, `_cached_cache_stats`, `_token_history`, `_comms_log`, `_pending_comms`, `_pending_tool_calls`, `_pending_history_adds`, `_ask_tool_data`, `_pending_mma_approvals`, `_pending_mma_spawns`, `_token_stats`, `vendor_quota`. Plus `Metadata()` construction at lines 2774, 2778, 3443. **Fix:** replace with typed per-aggregate dataclasses (`CommsLogEntry`, `HistoryMessage`, `ToolCall`, etc. — most already exist in `type_aliases.py`).
|
||||
- **GAP-C3 (Layer 3 — `aggregate.py` FileItem slippage, 10 sites):** `file_items: list[Metadata]` throughout + `NIL_METADATA: Metadata = {}` sentinel at line 50. **Fix:** change to `list[FileItem]` (the `FileItem` dataclass exists in `src/project_files.py`, aliased in `type_aliases.py:149`).
|
||||
- **GAP-C4 (scattered non-boundary `Metadata` fields):** `personas.py:22` `preferred_models: list[Metadata]`, `workspace_manager.py:16` `panel_states: Metadata`, `orchestrator_pm.py:57` `generate_tracks(project_config: Metadata) -> list[Metadata]`. Triage per-site.
|
||||
- **GAP-C5 (dead/deprecated code to delete):** `src/openai_schemas.py:108` `to_legacy_dict()` — zero callers, dead code. `src/app_controller.py:4973` `_push_mma_state_update` — marked DEPRECATED, delegates to `_result` variant; verify no callers, then delete.
|
||||
- **GAP-C6 (test-side migration, 27 files):** the 27 test files in GAP-B5 migrate as part of Front B, but the typed-dataclass migration in GAP-C2/C3 may break tests that construct `Metadata({...})` fixtures — those tests need to construct the new typed dataclasses instead.
|
||||
|
||||
## Goals
|
||||
|
||||
- **G1.** Gemini CLI adapter implementation fully removed from `src/` + `tests/` + docs. The `gemini_cli` provider no longer exists; PROVIDERS has 7 entries (down from 8). The 9 sim tests that used `gemini_cli` + `mock_gemini_cli.py` now use a `mock` provider + the same script.
|
||||
- **G2.** Test suite downsized by ~45-60 files / ~300-400 tests without losing ongoing behavioral coverage. Tier 1-4 cruft deleted or consolidated; the suite is leaner and the green tautologies are gone.
|
||||
- **G3.** `Metadata` type usage reduced to TOML/JSON boundary functions only. The 38-site MCP dispatch inversion is flipped. `app_controller.py` in-memory state uses typed per-aggregate dataclasses. `aggregate.py` uses `list[FileItem]`.
|
||||
- **G4.** The 3 fix-not-skip candidates are fixed (Gemini 503 calls mocked, not skipped).
|
||||
- **G5.** `src/models.py` shim callers in tests reduced to the 2 self-test files (which test the shim itself). All other test imports migrate to direct subsystem imports.
|
||||
- **G6.** Docs + conductor docs updated to reflect the 7-provider surface + the Metadata-reduction.
|
||||
|
||||
## Functional Requirements
|
||||
|
||||
### FR1: Gemini CLI Removal (Front A)
|
||||
|
||||
- Delete `src/gemini_cli_adapter.py`.
|
||||
- Edit `src/ai_client.py`: remove the import (line 49), the PROVIDERS entry (line 62), the module state (line 164), the 3 functions (`_list_gemini_cli_models`, `_send_gemini_cli`, `_send_cli_round_result`), and the ~8 dispatch branches.
|
||||
- Edit `src/app_controller.py`: remove the ~11 sites (state field, settable/gettable maps, `_update_gcli_adapter()`, project load/save, init).
|
||||
- Edit `src/gui_2.py`: remove the 2 blocks.
|
||||
- Edit `src/project_manager.py:126`: delete the default config entry.
|
||||
- Edit `src/api_hooks.py:88, 941-942`: delete the docstring line + simplify the HookServer auto-start.
|
||||
- Delete 7 test files (the gemini_cli-specific tests).
|
||||
- Introduce a `mock` provider in `ai_client.py` (or repurpose the existing `"mock"` model special case at line 558) that routes to `tests/mock_gemini_cli.py`. Rewrite the 9 sim tests to use `mock` instead of `gemini_cli`.
|
||||
- Update 7 docs + 5 conductor docs.
|
||||
|
||||
### FR2: Test Suite Cleanup (Front B)
|
||||
|
||||
- Delete `tests/test_generate_chronology.py` + `tests/test_chronology_quality_gate.py` (guaranteed-broken).
|
||||
- Consolidate the 7 `test_scavenge_*.py` into one `test_directive_structure.py`.
|
||||
- Review + delete or rewrite the deprecated-module test files (`test_mma_skeleton.py`, `test_arch_boundary_phase1.py`).
|
||||
- Review the ~15 `test_*_phase*.py` files; merge still-relevant assertions into the general files; delete the rest.
|
||||
- Migrate the 27 `src.models` test importers to direct subsystem imports.
|
||||
- Extract a shared `mock_controller` fixture from the ~8 files with the boilerplate patch block.
|
||||
- Fix the 3 fix-not-skip candidates by mocking `summarize.summarise_file`'s Gemini call.
|
||||
- Audit `test_gui_2_result.py` (120KB); split into per-feature files + delete obsolete snapshots.
|
||||
|
||||
### FR3: Metadata-Type Reduction (Front C)
|
||||
|
||||
- Flip the MCP dispatch inversion: update `dispatch()` + `async_dispatch()` + 22 consumer call sites to use the `_result` variants; delete the 38 str wrappers.
|
||||
- Replace `app_controller.py` in-memory `Metadata` state with typed per-aggregate dataclasses.
|
||||
- Change `aggregate.py` `file_items: list[Metadata]` → `list[FileItem]`; update `NIL_METADATA` sentinel.
|
||||
- Triage + fix the scattered non-boundary `Metadata` fields (`personas.py`, `workspace_manager.py`, `orchestrator_pm.py`).
|
||||
- Delete `src/openai_schemas.py:108` `to_legacy_dict()` (dead code).
|
||||
- Verify + delete `src/app_controller.py:4973` `_push_mma_state_update` (DEPRECATED).
|
||||
- Migrate the test fixtures that construct `Metadata({...})` to construct the new typed dataclasses.
|
||||
|
||||
### FR4: Verification
|
||||
|
||||
- The 4 audit scripts (`audit_main_thread_imports.py`, `audit_no_models_config_io.py`, `audit_weak_types.py --strict`, `audit_exception_handling.py --strict`) pass.
|
||||
- The full test suite batch run passes (per the Isolated-Pass Verification Fallacy rule — batch green is the only verification that matters).
|
||||
- `grep -r "gemini_cli" src/` returns only the `GEMINI_CLI_HOOK_CONTEXT` env-var references in `api_hooks.py` (if the user chose to keep the meta-tooling naming) or nothing (if the user chose to purge).
|
||||
- `grep -r "from src.models import" tests/` returns only the 2 self-test files.
|
||||
- `grep -r "list\[Metadata\]" src/app_controller.py` returns nothing (in-memory state migrated).
|
||||
|
||||
## Non-Functional Requirements
|
||||
|
||||
- **No testing-integrity loss:** every behavioral assertion that's still relevant must survive the cleanup. The deletion criteria are: (a) guaranteed-broken (imports from deleted modules), (b) permanently-green tautology (one-time verification that shipped), (c) redundant (covered by a general test file), (d) deprecated-module reference (the module is gone/deprecated). Behavioral assertions that are still catching real regressions stay.
|
||||
- **Per-file atomic commits** per workflow.md. Each Front-A file deletion + each Front-B test consolidation + each Front-C migration is its own commit.
|
||||
- **1-space indentation** per `conductor/code_styleguides/python.md` §1.
|
||||
- **Result[T, ErrorInfo]** return types per `conductor/code_styleguides/error_handling.md`. The Front-C dispatch flip is the largest application of this convention.
|
||||
- **Typed `@dataclass(frozen=True, slots=True)`** for the new in-memory state types per `conductor/code_styleguides/data_oriented_design.md` §8.5.
|
||||
- **CRLF line endings** on Windows.
|
||||
- **No new `src/<thing>.py` files** per AGENTS.md "File Size and Naming Convention" — the new typed dataclasses (if any) go in `src/type_aliases.py` or `src/mma.py` (the per-system files that already own the typed aggregates).
|
||||
- **No diagnostic noise in production code** per workflow.md "Process Anti-Patterns" §5.
|
||||
|
||||
## Architecture Reference
|
||||
|
||||
- **`conductor/code_styleguides/data_oriented_design.md`** §8.5 — the Python Type Promotion Mandate (the canonical rule this track advances).
|
||||
- **`conductor/code_styleguides/error_handling.md`** — the Result[T] + NIL_T sentinel pattern (the convention the Front-C dispatch flip applies).
|
||||
- **`conductor/code_styleguides/python.md`** §17 — the LLM Default Anti-Patterns (the banned patterns this track eliminates more of).
|
||||
- **`docs/guide_ai_client.md`** — the per-source-file guide that needs the Gemini CLI sections removed.
|
||||
- **`docs/guide_app_controller.md`** — the per-source-file guide for `app_controller.py` (the Front-C in-memory state migration).
|
||||
- **`docs/guide_mcp_client.md`** — the per-source-file guide for `mcp_client.py` (the Front-C dispatch flip).
|
||||
- **The 3 audit reports** from this track's research phase (the explore-agent outputs documenting the Gemini CLI inventory, the test-suite cruft map, and the legacy-API audit) — attached as track research artifacts.
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- **Meta-tooling `GEMINI_CLI_HOOK_CONTEXT` env var + `scripts/cli_tool_bridge.py` + `scripts/mma_exec.py` + `docs/guide_meta_boundary.md`.** These are external-agent-toolchain references, NOT the provider. Recommend a separate follow-up track if the user wants to purge the naming.
|
||||
- **The `twitter_threads_extraction_20260705` track** (separate, in-flight) — unrelated to this cleanup.
|
||||
- **The RAG subsystem** — the `rag_engine.py` Optional[T] ban already holds; the `dict[str, Any]` sites in rag_engine.py are all ChromaDB/JSON boundary (legitimate).
|
||||
- **The `vendor_capabilities.py` inlining** — already done per `docs/guide_models.md`; `test_vendor_capabilities.py` already imports from `src.ai_client` (correct).
|
||||
- **Historical/conductor archive content** — per workflow.md, `conductor/archive/` + `docs/reports/` + `docs/transcripts/` are not updated retroactively.
|
||||
- **GUI feature work** — no new GUI features; only removal of the gemini_cli provider panel.
|
||||
- **The `mock` provider's full capability surface** — the track introduces just enough of a `mock` provider to keep the 9 sim tests working; a full mock-provider implementation (with configurable responses, error injection, etc.) is a future track.
|
||||
|
||||
## Track Structure
|
||||
|
||||
Single track, 3 phases (one per front). The fronts are sequenced: Front A (Gemini CLI removal) first because it deletes test files + rewrites 9 more, which is the entry point for Front B (test cleanup). Front C (metadata reduction) is last because it's the largest production-code change and the test cleanup in Front B needs to reflect the typed-dataclass migration.
|
||||
|
||||
The track is large. If the user wants to split it, the natural split points are: Front A as one track (Gemini CLI removal + sim-test rewrite), Front B+C as a second track (test cleanup + metadata reduction). But the user framed them as one effort, so this spec keeps them bundled.
|
||||
|
||||
## Verification
|
||||
|
||||
- **VC1:** `src/gemini_cli_adapter.py` does not exist. `grep -r "gemini_cli" src/` returns only the meta-tooling env-var references (or nothing if the user purged those too).
|
||||
- **VC2:** `PROVIDERS` in `src/ai_client.py` has 7 entries (no `gemini_cli`).
|
||||
- **VC3:** `tests/test_generate_chronology.py` + `tests/test_chronology_quality_gate.py` do not exist.
|
||||
- **VC4:** The 7 `test_scavenge_*.py` files do not exist; `tests/test_directive_structure.py` exists and checks the general invariant.
|
||||
- **VC5:** `grep -r "from src.models import" tests/` returns only the 2 self-test files (`test_models_no_top_level_*.py`).
|
||||
- **VC6:** `grep -r "list\[Metadata\]" src/app_controller.py` returns nothing.
|
||||
- **VC7:** `src/mcp_client.py` has no str-returning wrappers (the 38 are deleted; `dispatch()` returns `Result`).
|
||||
- **VC8:** `src/aggregate.py` uses `list[FileItem]`, not `list[Metadata]`.
|
||||
- **VC9:** The 3 fix-not-skip tests are fixed (no `@pytest.mark.skip` for the Gemini 503 reason).
|
||||
- **VC10:** The 4 audit scripts pass.
|
||||
- **VC11:** The full test suite batch run passes.
|
||||
- **VC12:** `src/openai_schemas.py:108` `to_legacy_dict()` is deleted.
|
||||
|
||||
## See Also
|
||||
|
||||
- **`conductor/tracks/twitter_threads_extraction_20260705/spec.md`** — the sibling in-flight track (unrelated; referenced only because it's the other active track).
|
||||
- **`docs/reports/ARCHIVE_REVIEW_20260705.md`** — the archive review (this track advances several of its ranked follow-up items: #1 typed_rag_return_type is adjacent to GAP-C2; #6 mcp_client_tool_surface_assert_removal is GAP-C1; #7 gui_2_hasattr_removal is adjacent to Front C).
|
||||
- **The 3 audit reports** from this track's research (attached as research artifacts in the track folder).
|
||||
@@ -0,0 +1,105 @@
|
||||
# Track state for test_suite_cleanup_gemini_cli_removal_20260705
|
||||
# Initialized by Tier 1 Orchestrator on 2026-07-05.
|
||||
# 3 fronts: Gemini CLI removal + test suite cleanup + metadata-type reduction.
|
||||
|
||||
[meta]
|
||||
track_id = "test_suite_cleanup_gemini_cli_removal_20260705"
|
||||
name = "Test Suite Cleanup + Gemini CLI Adapter Removal + Metadata-Type Reduction"
|
||||
status = "active"
|
||||
current_phase = 0
|
||||
last_updated = "2026-07-05"
|
||||
|
||||
[blocked_by]
|
||||
# None. The Gemini CLI removal is independent; the test cleanup is independent; the metadata reduction is independent.
|
||||
|
||||
[blocks]
|
||||
# None. The track advances the ARCHIVE_REVIEW_20260705.md follow-up items (#1, #2, #6) but doesn't block them.
|
||||
|
||||
[phases]
|
||||
phase_1 = { status = "pending", checkpointsha = "", name = "Front A — Gemini CLI Adapter Removal (src + tests + docs + mock provider)" }
|
||||
phase_2 = { status = "pending", checkpointsha = "", name = "Front B — Test Suite Cleanup (delete broken + consolidate tautologies + migrate shims + fix-not-skip)" }
|
||||
phase_3 = { status = "pending", checkpointsha = "", name = "Front C — Metadata-Type Reduction (MCP dispatch flip + app_controller state + aggregate FileItem + dead code)" }
|
||||
|
||||
[tasks]
|
||||
# Phase 1 — Gemini CLI Removal
|
||||
t1_1 = { status = "pending", commit_sha = "", description = "Delete src/gemini_cli_adapter.py" }
|
||||
t1_2 = { status = "pending", commit_sha = "", description = "Edit src/ai_client.py — remove import + PROVIDERS entry + module state + 3 functions + 8 dispatch branches" }
|
||||
t1_3 = { status = "pending", commit_sha = "", description = "Edit src/app_controller.py — remove ~11 gemini_cli sites" }
|
||||
t1_4 = { status = "pending", commit_sha = "", description = "Edit src/gui_2.py — remove 2 gemini_cli blocks" }
|
||||
t1_5 = { status = "pending", commit_sha = "", description = "Edit src/project_manager.py:126 + src/api_hooks.py:88,941-942" }
|
||||
t1_6 = { status = "pending", commit_sha = "", description = "Delete 7 gemini_cli test files" }
|
||||
t1_7 = { status = "pending", commit_sha = "", description = "Introduce mock provider in src/ai_client.py (routes to tests/mock_gemini_cli.py)" }
|
||||
t1_8 = { status = "pending", commit_sha = "", description = "Rewrite 9 sim test files: gemini_cli -> mock" }
|
||||
t1_9 = { status = "pending", commit_sha = "", description = "Minor edits in 6+ gemini_cli-reference test files (provider lists, monkeypatches, comments)" }
|
||||
t1_10 = { status = "pending", commit_sha = "", description = "Update 7 docs + 5 conductor docs (remove gemini_cli, update provider count 8->7)" }
|
||||
t1_11 = { status = "pending", commit_sha = "", description = "Phase 1 checkpoint + batch run" }
|
||||
|
||||
# Phase 2 — Test Suite Cleanup
|
||||
t2_1 = { status = "pending", commit_sha = "", description = "Delete 2 guaranteed-broken chronology test files (import from deleted scripts.audit.*)" }
|
||||
t2_2 = { status = "pending", commit_sha = "", description = "Consolidate 7 test_scavenge_*.py into 1 test_directive_structure.py" }
|
||||
t2_3 = { status = "pending", commit_sha = "", description = "Review + delete/rewrite deprecated-module test files (test_mma_skeleton, test_arch_boundary_phase1)" }
|
||||
t2_4 = { status = "pending", commit_sha = "", description = "Review + consolidate ~15 test_*_phase*.py files" }
|
||||
t2_5 = { status = "pending", commit_sha = "", description = "Migrate 27 src.models test importers to direct subsystem imports" }
|
||||
t2_6 = { status = "pending", commit_sha = "", description = "Extract shared mock_controller fixture from ~8 boilerplate-patch files" }
|
||||
t2_7 = { status = "pending", commit_sha = "", description = "Fix 3 fix-not-skip candidates (mock Gemini 503 in summarize.summarise_file)" }
|
||||
t2_8 = { status = "pending", commit_sha = "", description = "Audit + split test_gui_2_result.py (120KB, 101 tests) into per-feature files" }
|
||||
t2_9 = { status = "pending", commit_sha = "", description = "Phase 2 checkpoint + full suite batch run" }
|
||||
|
||||
# Phase 3 — Metadata-Type Reduction
|
||||
t3_1 = { status = "pending", commit_sha = "", description = "Flip MCP dispatch inversion: dispatch()+async_dispatch()+22 consumers -> _result variants; delete 38 str wrappers" }
|
||||
t3_2 = { status = "pending", commit_sha = "", description = "Migrate app_controller.py ~40 Metadata in-memory state sites to typed per-aggregate dataclasses" }
|
||||
t3_3 = { status = "pending", commit_sha = "", description = "Fix aggregate.py file_items: list[Metadata] -> list[FileItem]; NIL_METADATA -> typed empty sentinel" }
|
||||
t3_4 = { status = "pending", commit_sha = "", description = "Triage scattered non-boundary Metadata fields (personas.py, workspace_manager.py, orchestrator_pm.py)" }
|
||||
t3_5 = { status = "pending", commit_sha = "", description = "Delete dead code: openai_schemas.py:108 to_legacy_dict() + app_controller.py:4973 _push_mma_state_update" }
|
||||
t3_6 = { status = "pending", commit_sha = "", description = "Migrate test fixtures that construct Metadata({...}) to typed dataclass constructors" }
|
||||
t3_7 = { status = "pending", commit_sha = "", description = "Update docs (guide_app_controller, guide_mcp_client, guide_models, type_aliases styleguide)" }
|
||||
t3_8 = { status = "pending", commit_sha = "", description = "Run 4 audit scripts + full test suite batch" }
|
||||
t3_9 = { status = "pending", commit_sha = "", description = "Phase 3 checkpoint + TRACK_COMPLETION report" }
|
||||
t3_10 = { status = "pending", commit_sha = "", description = "Conductor — User Manual Verification (PAUSE for user confirmation)" }
|
||||
t3_11 = { status = "pending", commit_sha = "", description = "Add chronology row + archive the track" }
|
||||
|
||||
[verification]
|
||||
vc1_gemini_cli_removed = false
|
||||
vc2_providers_7_entries = false
|
||||
vc3_chronology_tests_deleted = false
|
||||
vc4_scavenge_consolidated = false
|
||||
vc5_models_shim_migrated = false
|
||||
vc6_app_controller_no_list_metadata = false
|
||||
vc7_mcp_dispatch_flipped = false
|
||||
vc8_aggregate_uses_fileitem = false
|
||||
vc9_fix_not_skip_fixed = false
|
||||
vc10_audit_scripts_pass = false
|
||||
vc11_batch_green = false
|
||||
vc12_to_legacy_dict_deleted = false
|
||||
|
||||
[front_a_summary]
|
||||
gemini_cli_adapter_py_deleted = false
|
||||
ai_client_functions_removed = 0
|
||||
ai_client_dispatch_branches_removed = 0
|
||||
app_controller_sites_removed = 0
|
||||
gui_2_blocks_removed = 0
|
||||
test_files_deleted = 0
|
||||
sim_tests_rewritten = 0
|
||||
mock_provider_introduced = false
|
||||
docs_updated = 0
|
||||
|
||||
[front_b_summary]
|
||||
chronology_tests_deleted = false
|
||||
scavenge_files_consolidated = false
|
||||
deprecated_module_tests_reviewed = 0
|
||||
phase_named_tests_consolidated = 0
|
||||
shim_importers_migrated = 0
|
||||
mock_controller_fixture_extracted = false
|
||||
fix_not_skip_fixed = 0
|
||||
gui_2_result_audited = false
|
||||
test_count_before = 2133
|
||||
test_count_after = 0
|
||||
|
||||
[front_c_summary]
|
||||
mcp_str_wrappers_deleted = 0
|
||||
mcp_dispatch_flipped = false
|
||||
app_controller_metadata_sites_migrated = 0
|
||||
aggregate_fileitem_migrated = false
|
||||
scattered_metadata_triaged = 0
|
||||
dead_code_deleted = 0
|
||||
test_fixtures_migrated = 0
|
||||
Reference in New Issue
Block a user