{
  "track_id": "public_api_migration_and_ui_polish_20260615",
  "name": "Public API Migration + UI Polish Test Cleanup",
  "initialized": "2026-06-15",
  "owner": "tier2-tech-lead",
  "priority": "A",
  "status": "completed",
  "type": "refactor + bugfix + test_cleanup + documentation",
  "scope": {
    "new_files": [],
    "modified_files": [
      "src/ai_client.py",
      "src/conductor_tech_lead.py",
      "src/orchestrator_pm.py",
      "src/multi_agent_conductor.py",
      "tests/test_ai_client_cli.py",
      "tests/test_ai_cache_tracking.py",
      "tests/test_ai_client_result.py",
      "tests/test_api_events.py",
      "tests/test_deepseek_provider.py",
      "tests/test_gemini_cli_edge_cases.py",
      "tests/test_gemini_cli_integration.py",
      "tests/test_gemini_cli_parity_regression.py",
      "tests/test_gui2_mcp.py",
      "tests/test_tier4_interceptor.py",
      "tests/test_token_usage.py",
      "tests/test_symbol_parsing.py",
      "tests/test_qwen_provider.py",
      "tests/test_discussion_truncate_layout.py",
      "tests/test_log_management_refresh.py",
      "pyproject.toml",
      "docs/guide_ai_client.md",
      "conductor/product-guidelines.md"
    ],
    "deleted_files": [
      "tests/test_deprecation_warnings.py"
    ]
  },
  "blocked_by": [],
  "blocks": [
    "data_structure_strengthening_20260606",
    "mcp_architecture_refactor_20260606 (transitively)"
  ],
  "estimated_phases": 7,
  "spec": "spec.md",
  "plan": "plan.md",

  "regressions_and_pre_existing_failures": [
    {
      "id": "G1_conductor_tech_lead_send",
      "severity": "high",
      "category": "production_deprecation",
      "introduced_by": "data_oriented_error_handling_20260606 commit 73cf321c (marked send() @deprecated)",
      "file_line": "src/conductor_tech_lead.py:68",
      "symptom": "Production code uses deprecated ai_client.send() (emits DeprecationWarning at runtime)",
      "fix_phase": 1,
      "fix": "Migrate to ai_client.send_result() with Result handling (log to comms on error, return None)"
    },
    {
      "id": "G2_orchestrator_pm_send",
      "severity": "high",
      "category": "production_deprecation",
      "introduced_by": "data_oriented_error_handling_20260606 commit 73cf321c",
      "file_line": "src/orchestrator_pm.py:86",
      "symptom": "Production code uses deprecated ai_client.send()",
      "fix_phase": 1,
      "fix": "Migrate to ai_client.send_result() with Result handling (log to comms on error, return None)"
    },
    {
      "id": "G3_multi_agent_conductor_send",
      "severity": "high",
      "category": "production_deprecation",
      "introduced_by": "data_oriented_error_handling_20260606 commit 73cf321c",
      "file_line": "src/multi_agent_conductor.py:591",
      "symptom": "Production code uses deprecated ai_client.send() (8-arg call with 5 callbacks)",
      "fix_phase": 1,
      "fix": "Migrate to ai_client.send_result() with per-ticket Result handling (log to worker_comms_callback on error, return sentinel value so worker exits with non-zero status)"
    },
    {
      "id": "G4_test_ai_client_cli",
      "severity": "medium",
      "category": "test_deprecation",
      "file_line": "tests/test_ai_client_cli.py:22",
      "fix_phase": 2,
      "fix": "Migrate to send_result() + assert result.ok"
    },
    {
      "id": "G5_test_ai_cache_tracking",
      "severity": "medium",
      "category": "test_deprecation",
      "file_line": "tests/test_ai_cache_tracking.py:47",
      "fix_phase": 2,
      "fix": "Migrate to send_result() + assert result.ok"
    },
    {
      "id": "G6_test_ai_client_result",
      "severity": "medium",
      "category": "test_deprecation",
      "file_line": "tests/test_ai_client_result.py:10-25 (3 sites; 1 to delete, 2 to migrate)",
      "fix_phase": 2,
      "fix": "Delete test_send_deprecated_emits_warning (obsolete after Phase 6); migrate the other 2 send() tests to send_result(); keep test_send_result_does_not_emit_deprecation as regression test"
    },
    {
      "id": "G7_test_api_events",
      "severity": "medium",
      "category": "test_deprecation",
      "file_line": "tests/test_api_events.py:63,106",
      "fix_phase": 2,
      "fix": "Migrate 2 sites to send_result()"
    },
    {
      "id": "G8_test_deepseek_provider",
      "severity": "medium",
      "category": "test_deprecation",
      "file_line": "tests/test_deepseek_provider.py:31,54,96,122,142,171 (6 sites)",
      "fix_phase": 2,
      "fix": "Migrate 6 sites to send_result() (1 atomic commit for the file)"
    },
    {
      "id": "G9_test_gemini_cli_edge_cases",
      "severity": "medium",
      "category": "test_deprecation",
      "file_line": "tests/test_gemini_cli_edge_cases.py:38",
      "fix_phase": 2,
      "fix": "Migrate to send_result()"
    },
    {
      "id": "G10_test_gemini_cli_integration",
      "severity": "medium",
      "category": "test_deprecation",
      "file_line": "tests/test_gemini_cli_integration.py:15,29",
      "fix_phase": 2,
      "fix": "Migrate 2 sites to send_result()"
    },
    {
      "id": "G11_test_gemini_cli_parity_regression",
      "severity": "medium",
      "category": "test_deprecation",
      "file_line": "tests/test_gemini_cli_parity_regression.py:12",
      "fix_phase": 2,
      "fix": "Migrate to send_result()"
    },
    {
      "id": "G12_test_gui2_mcp",
      "severity": "medium",
      "category": "test_deprecation",
      "file_line": "tests/test_gui2_mcp.py:47",
      "fix_phase": 2,
      "fix": "Migrate to send_result()"
    },
    {
      "id": "G13_test_tier4_interceptor",
      "severity": "medium",
      "category": "test_deprecation",
      "file_line": "tests/test_tier4_interceptor.py:83",
      "fix_phase": 2,
      "fix": "Migrate to send_result() (with Result(data=...) wrapper for the qa_callback mock)"
    },
    {
      "id": "G14_test_token_usage",
      "severity": "medium",
      "category": "test_deprecation",
      "file_line": "tests/test_token_usage.py:34",
      "fix_phase": 2,
      "fix": "Migrate to send_result()"
    },
    {
      "id": "G15_test_symbol_parsing",
      "severity": "high",
      "category": "test_mock_bug",
      "file_line": "tests/test_symbol_parsing.py:45,74",
      "symptom": "Mocks src.ai_client.send but production now uses send_result; mock receives 0 calls; test fails with 'send was called 0 times'",
      "fix_phase": 4,
      "fix": "Change patch('src.ai_client.send') to patch('src.ai_client.send_result') with return_value=Result(data='mocked response')"
    },
    {
      "id": "G16_test_qwen_provider",
      "severity": "high",
      "category": "test_mock_bug",
      "file_line": "tests/test_qwen_provider.py:17,27",
      "symptom": "_send_qwen() now returns Result[str] (per data_oriented_error_handling refactor); tests assert against raw str",
      "fix_phase": 3,
      "fix": "Change 'assert result == x' to 'assert result.ok and result.data == x' (same pattern as doeh_test_thinking_cleanup used for grok/llama/llama_native)"
    },
    {
      "id": "G17_test_discussion_truncate_layout",
      "severity": "high",
      "category": "ui_polish_test_bug",
      "file_line": "tests/test_discussion_truncate_layout.py:7",
      "symptom": "Test uses find() which locates the comment block at src/gui_2.py:5113; the 200-char snippet doesn't reach the actual code at line 5130. Production code (set_next_item_width(140) + drag_int) is already correct (user commit d0b06575)",
      "fix_phase": 5,
      "fix": "Change src.find(marker) to src.rfind(marker) to locate the actual code, not the comment"
    },
    {
      "id": "G18_test_log_management_refresh",
      "severity": "high",
      "category": "ui_polish_test_bug",
      "file_line": "tests/test_log_management_refresh.py:6",
      "symptom": "Test uses find() which locates the comment block at src/gui_2.py:2090; the 400-char snippet doesn't reach the actual code at line 2111. Production code (in-place load_registry()) is already correct (user commit df7bda6e)",
      "fix_phase": 5,
      "fix": "Change src.find(marker) to src.rfind(marker) to locate the actual code, not the comment"
    },
    {
      "id": "G19_deprecated_send_function",
      "severity": "high",
      "category": "deprecation_removal",
      "file_line": "src/ai_client.py:2939-3040",
      "symptom": "Legacy send() function still exists; emits DeprecationWarning at runtime; filterwarnings in pyproject.toml silences it",
      "fix_phase": 6,
      "fix": "Remove the @deprecated decorator + the entire send() function body; remove the filterwarnings entry in pyproject.toml:46-47; delete tests/test_deprecation_warnings.py (both tests are obsolete)"
    }
  ],

  "pre_existing_failures_fixed": [
    {
      "id": "PE_1",
      "test": "tests/test_qwen_provider.py::test_send_qwen_routes_to_dashscope",
      "fix_phase": 3,
      "root_cause": "_send_qwen() returns Result[str]; test asserts against raw str"
    },
    {
      "id": "PE_2",
      "test": "tests/test_qwen_provider.py::test_qwen_vision_vl_model_accepts_image",
      "fix_phase": 3,
      "root_cause": "Same as PE_1"
    },
    {
      "id": "PE_3",
      "test": "tests/test_symbol_parsing.py::test_handle_request_event_appends_definitions",
      "fix_phase": 4,
      "root_cause": "Mocks src.ai_client.send but production uses send_result"
    },
    {
      "id": "PE_4",
      "test": "tests/test_symbol_parsing.py::test_handle_request_event_no_symbols",
      "fix_phase": 4,
      "root_cause": "Same as PE_3"
    },
    {
      "id": "PE_5",
      "test": "tests/test_discussion_truncate_layout.py::test_keep_pairs_input_uses_adequate_width",
      "fix_phase": 5,
      "root_cause": "Test uses find() which locates the comment block, not the actual code at line 5130"
    },
    {
      "id": "PE_6",
      "test": "tests/test_log_management_refresh.py::test_refresh_registry_button_calls_load_registry",
      "fix_phase": 5,
      "root_cause": "Test uses find() which locates the comment block, not the actual code at line 2111"
    }
  ],

  "pre_existing_failures_remaining": [
    {
      "id": "PR_1",
      "test": "tests/test_rag_integration.py::test_rag_integration",
      "root_cause": "Pre-existing RAG subsystem issue (NoneType.get error in RAG config lookup code)",
      "defer_to": "RAG subsystem track (planned; not yet specced)"
    },
    {
      "id": "PR_2",
      "test": "tests/test_rag_phase4_final_verify.py::test_phase4_final_verify",
      "root_cause": "Same as PR_1",
      "defer_to": "RAG subsystem track"
    },
    {
      "id": "PR_3",
      "test": "tests/test_rag_phase4_stress.py::test_rag_large_codebase_verification_sim",
      "root_cause": "Same as PR_1",
      "defer_to": "RAG subsystem track"
    },
    {
      "id": "PR_4",
      "test": "tests/test_rag_visual_sim.py::test_rag_full_lifecycle_sim",
      "root_cause": "Same as PR_1",
      "defer_to": "RAG subsystem track"
    }
  ],

  "deferred_to_followup_tracks": [
    {
      "id": "rag_test_failures",
      "title": "RAG Subsystem Test Fixes",
      "description": "Fix the 4 pre-existing RAG test failures (test_rag_integration, test_rag_phase4_final_verify, test_rag_phase4_stress, test_rag_visual_sim). The error is in RAG config lookup code, not AI client code. A partial fix was attempted in commit 16412ad5 (RAG Phase 4 dim-mismatch recovery).",
      "track_status": "recommended; not yet specced"
    },
    {
      "id": "private_api_rename",
      "title": "Private API Rename (_send_<vendor> -> _send_<vendor>_result)",
      "description": "Per data_oriented_error_handling_20260606 spec §3.5 line 611, the original plan was to rename the private _send_<vendor>() functions to _send_<vendor>_result() to match their Result return type. The rename was NOT done in the data_oriented_error_handling track; the tests work with the current names. A future track could do the rename if needed.",
      "track_status": "not needed for now; tests work with current names"
    },
    {
      "id": "data_structure_strengthening_20260606",
      "title": "Data Structure Strengthening (Type Aliases + NamedTuples)",
      "description": "Introduce 6 TypeAlias definitions in src/type_aliases.py; replace 370+ anonymous dict[str, Any] sites in 6 high-traffic files (src/ai_client.py, src/app_controller.py, src/models.py, src/api_hook_client.py, src/project_manager.py, src/aggregate.py). The 23 lower-impact files remain. Spec already exists; plan pending.",
      "track_status": "ready to start; blocked by this track (cleaner Result API usage makes type-alias replacement easier)"
    },
    {
      "id": "live_gui_mock_injection_20260615",
      "title": "Live GUI Mock Injection Infrastructure",
      "description": "Infrastructure for mock injection into the live_gui subprocess. Unblocks proper end-to-end live_gui + AI client tests.",
      "track_status": "recommended; not yet specced"
    }
  ],

  "verification_criteria": {
    "g1_three_production_call_sites_migrated": "uv run rg 'ai_client\\.send\\(' src/ returns 0 hits",
    "g2_twelve_test_files_migrated": "uv run rg 'ai_client\\.send\\(' tests/ returns 0 hits",
    "g3_qwen_test_passes": "uv run pytest tests/test_qwen_provider.py -v passes 5/5 (was 3/5; fixes 2 pre-existing failures)",
    "g4_symbol_parsing_test_passes": "uv run pytest tests/test_symbol_parsing.py -v passes 2/2 (fixes 2 pre-existing failures)",
    "g5_truncate_layout_test_passes": "uv run pytest tests/test_discussion_truncate_layout.py -v passes 1/1 (fixes 1 pre-existing failure)",
    "g6_log_management_refresh_test_passes": "uv run pytest tests/test_log_management_refresh.py -v passes 1/1 (fixes 1 pre-existing failure)",
    "g7_deprecated_send_removed": "uv run rg 'def send\\(' src/ai_client.py returns 0 hits (only def send_result() should remain)",
    "g8_test_deprecation_warnings_deleted": "tests/test_deprecation_warnings.py does not exist",
    "g9_filterwarnings_removed": "uv run rg 'ignore:Use ai_client.send_result' pyproject.toml returns 0 hits",
    "g10_guide_ai_client_deprecation_removed": "uv run rg -i 'deprecat' docs/guide_ai_client.md | grep -i send returns 0 hits",
    "g11_product_guidelines_deprecation_removed": "uv run rg -i 'send.*deprecat|deprecat.*send' conductor/product-guidelines.md returns 0 hits",
    "g12_no_new_regressions": "uv run pytest tests/ shows 4 fewer failures than the pre-track baseline (10 - 6 = 4 RAG failures remain); no new failures",
    "g13_per_task_atomic_commits": "~28 git commits; each commit is buildable + testable",
    "g14_per_commit_git_notes": "All ~28 commits have git notes summarizing the task",
    "g15_style_preserved": "1-space indentation, no comments, type hints in all changed code; uv run python -c 'import ast; ast.parse(open(\"src/ai_client.py\").read())' succeeds"
  },

  "fr_to_phase_mapping": {
    "G1_conductor_tech_lead_send": {
      "phase": 1,
      "fix_files": ["src/conductor_tech_lead.py:60-90"],
      "test_files": ["tests/test_conductor_tech_lead.py (if exists)"]
    },
    "G2_orchestrator_pm_send": {
      "phase": 1,
      "fix_files": ["src/orchestrator_pm.py:80-100"],
      "test_files": ["tests/test_orchestrator_pm.py (if exists)"]
    },
    "G3_multi_agent_conductor_send": {
      "phase": 1,
      "fix_files": ["src/multi_agent_conductor.py:580-605"],
      "test_files": ["tests/test_mma_concurrent_tracks_sim.py", "tests/test_mma_step_mode_sim.py", "tests/test_undo_redo_sim.py", "30+ MMA live_gui tests"]
    },
    "G4-G14_test_migration": {
      "phase": 2,
      "fix_files": ["tests/test_ai_client_cli.py", "tests/test_ai_cache_tracking.py", "tests/test_ai_client_result.py", "tests/test_api_events.py", "tests/test_deepseek_provider.py", "tests/test_gemini_cli_edge_cases.py", "tests/test_gemini_cli_integration.py", "tests/test_gemini_cli_parity_regression.py", "tests/test_gui2_mcp.py", "tests/test_tier4_interceptor.py", "tests/test_token_usage.py"],
      "min_test_count": 12
    },
    "G15_symbol_parsing_fix": {
      "phase": 4,
      "fix_files": ["tests/test_symbol_parsing.py:45,74"],
      "min_test_count": 2
    },
    "G16_qwen_test_fix": {
      "phase": 3,
      "fix_files": ["tests/test_qwen_provider.py:13-20, 22-31"],
      "min_test_count": 2
    },
    "G17_G18_ui_polish_test_fixes": {
      "phase": 5,
      "fix_files": ["tests/test_discussion_truncate_layout.py:7", "tests/test_log_management_refresh.py:6"],
      "min_test_count": 2
    },
    "G19_deprecation_removal": {
      "phase": 6,
      "fix_files": ["src/ai_client.py:2939-3040", "pyproject.toml:46-47"],
      "deleted_files": ["tests/test_deprecation_warnings.py"],
      "min_test_count": 0
    },
    "G20_doc_updates": {
      "phase": 7,
      "fix_files": ["docs/guide_ai_client.md", "conductor/product-guidelines.md"],
      "min_test_count": 0
    }
  },

  "estimated_effort": {
    "phase_1": "1 day - 3 production call sites migrated (1 hardest with 5 callbacks)",
    "phase_2": "1 day - 12 test files migrated to send_result() (mechanical)",
    "phase_3": "1 hour - 2 Qwen tests fixed",
    "phase_4": "30 min - 2 symbol_parsing tests fixed",
    "phase_5": "30 min - 2 UI Polish test bugs fixed (find -> rfind)",
    "phase_6": "30 min - deprecation removed (send() function + filterwarnings + test_deprecation_warnings.py deleted)",
    "phase_7": "1 hour - docs updated + full suite sweep + metadata + tracks.md",
    "total": "2-3 days Tier 2 work (16-24 hours)"
  },

  "risk_register": {
    "R1_multi_agent_conductor_migration_breaks_MMA": {
      "likelihood": "medium",
      "impact": "high",
      "mitigation": "TDD red first; verify a known MMA test fails before the fix; verify it passes after. Use the doeh_test_thinking_cleanup_20260615 G1 fix pattern (adapted for MMA's comms log instead of HTTPException)."
    },
    "R2_send_removal_breaks_indirect_imports": {
      "likelihood": "low",
      "impact": "medium",
      "mitigation": "Run 'rg ai_client\\.send\\( src/ tests/' before AND after Phase 6 to confirm 0 hits."
    },
    "R3_filterwarnings_removal_causes_test_failures": {
      "likelihood": "low",
      "impact": "low",
      "mitigation": "The filter was added in data_oriented_error_handling_20260606 specifically to silence send() deprecation; no other deprecation in the codebase is silenced by it. Verified by checking the rg history."
    },
    "R4_ui_polish_test_fixes_mask_real_production_bug": {
      "likelihood": "low",
      "impact": "medium",
      "mitigation": "The production code at src/gui_2.py:5130-5131 and :2111-2112 was already verified to have the correct values. The test bug is just the search logic."
    },
    "R5_qwen_test_fix_uses_different_pattern": {
      "likelihood": "low",
      "impact": "low",
      "mitigation": "Plan uses the same 'assert result.ok and result.data == x' pattern as doeh_test_thinking_cleanup_20260615 (commits d7e42a4a, 439a0ac0, dbdf9ba9)."
    },
    "R6_test_deprecation_warnings_deletion_misinterpreted": {
      "likelihood": "low",
      "impact": "low",
      "mitigation": "Both tests in the file are obsolete after send() removal. The first test cannot run without send(). The second test is trivially true. Document in the commit message."
    },
    "R7_rag_failures_regress_during_track": {
      "likelihood": "low",
      "impact": "medium",
      "mitigation": "Run full test suite in Phase 7 and compare to the pre-track baseline. The 4 RAG failures are documented as pre-existing with their defer-to track recorded."
    }
  },

  "critical_audit_findings": {
    "ui_polish_status": {
      "phase_1_markdown_tables": "SHIPPED (commit 79ac9210); src/markdown_table.py exists",
      "phase_2_keep_pairs": "Code SHIPPED (user commit d0b06575, src/gui_2.py:5130-5131); test FAILING (find() locates comment block, not code)",
      "phase_3_refresh_registry": "Code SHIPPED (user commit df7bda6e, src/gui_2.py:2111-2112); test FAILING (find() locates comment block, not code)",
      "phase_4_vendor_state": "SHIPPED (commit 3a864076); src/vendor_state.py exists",
      "phase_5_files_directory_tree": "SHIPPED (commit 74e02485); src/gui_2.py:render_files_and_media uses directory grouping"
    },
    "send_state": {
      "production_call_sites_remaining": 3,
      "production_call_sites_migrated_by_doeh_track": 2,
      "test_files_using_send_directly": 12,
      "test_files_using_send_directly_in_parent_spec": 63,
      "discrepancy_reason": "Parent spec (data_oriented_error_handling_20260606) verified 63 test files on 2026-06-11; since then, doeh_test_thinking_cleanup_20260615 migrated 11 of them (Phase 2 of that track), leaving 12 today. The current count is verified via rg 2026-06-15."
    },
    "deprecated_send_function_state": {
      "decorator": "src/ai_client.py:2939 (@deprecated from typing_extensions)",
      "function_body_lines": "src/ai_client.py:2940-3040",
      "filterwarnings_entry": "pyproject.toml:46-47 (filterwarnings = [\"ignore:Use ai_client.send_result.*:DeprecationWarning\"])",
      "obsolete_test_file": "tests/test_deprecation_warnings.py (2 tests; both will be deleted in Phase 6)"
    }
  }
}
