# Implementation Plan: MMA Agent Focus UX

Architecture reference: [docs/guide_mma.md](../../../docs/guide_mma.md)

**Prerequisite:** `feature_bleed_cleanup_20260302` Phase 1 must be complete (dead comms panel removed, line numbers stabilized).

---

## Phase 1: Tier Tagging at Emission [checkpoint: bc1a570]
Focus: Add `current_tier` context variable to `ai_client` and stamp it on every comms/tool entry at the point of emission. No UI changes â€” purely data layer.

- [x] Task 1.1: Add `current_tier` module variable to `ai_client.py`. 8d9f25d
- [x] Task 1.2: Stamp `source_tier` in `_append_comms`. 8d9f25d
- [x] Task 1.3: Set/clear `current_tier` in `run_worker_lifecycle` (Tier 3). 8d9f25d
- [x] Task 1.4: Set/clear `current_tier` in `generate_tickets` (Tier 2). 8d9f25d
- [x] Task 1.5: Migrate `_tool_log` from tuple to dict; update emission and storage. 8d9f25d
- [x] Task 1.6: Write tests for Phase 1. 8 tests, 12/12 passed. 8d9f25d

- [x] Task 1.7: Conductor â€” User Manual Verification. App renders, comms history panel intact. 00a196c
  - Launch app. Open a send in normal mode â€” confirm comms entries in Operations Hub > Comms History still render.
  - (MMA run not required at this phase â€” data layer only.)

---

## Phase 2: Tool Log Reader Migration [checkpoint: 865d8dd]
Focus: Update `_render_tool_calls_panel` to read dicts. No UI change â€” just fixes the access pattern before Phase 3 adds filter logic.

- [x] Task 2.1: Update `_render_tool_calls_panel` to use dict access. 865d8dd
  - **Location**: `gui_2.py:2989-3039`. Confirm with `get_file_slice(2989, 3042)`.
  - **What**: Replace `script, result, _ = self._tool_log[i_minus_one]` with:
    ```python
    entry = self._tool_log[i_minus_one]
    script = entry["script"]
    result = entry["result"]
    ```
  - All subsequent uses of `script` and `result` in the same loop body are unchanged.
  - **How**: Use `Edit` targeting the destructure line.
  - **Verify**: `py_check_syntax(gui_2.py)` passes; run tests.

- [x] Task 2.2: Write/run tests. 12/12 passed. 865d8dd
  - Run `uv run pytest tests/ -x -q`. Confirm tool log panel simulation tests (if any) pass.

- [x] Task 2.3: Conductor â€” User Manual Verification. 865d8dd
  - Launch app. Generate a script send (or use existing tool call in history). Confirm "Tool Calls" tab in Operations Hub renders correctly.

---

## Phase 3: Focus Agent UI + Filter Logic [checkpoint: b30e563]
Focus: Add the combo selector and filter the two log panels.

- [x] Task 3.1: Add `ui_focus_agent` state var to `App.__init__`. b30e563
- [x] Task 3.2: Add Focus Agent selector widget in Operations Hub. b30e563
  - **Location**: `gui_2.py` `_gui_func`, Operations Hub block (line ~1774). Confirm with `get_file_slice(1774, 1792)`. Current content:
    ```python
    if imgui.begin_tab_bar("OperationsTabs"):
    ```
  - **What**: Insert immediately before `if imgui.begin_tab_bar("OperationsTabs"):`:
    ```python
    imgui.text("Focus Agent:")
    imgui.same_line()
    focus_label = self.ui_focus_agent or "All"
    if imgui.begin_combo("##focus_agent", focus_label, imgui.ComboFlags_.width_fit_preview):
        if imgui.selectable("All", self.ui_focus_agent is None)[0]:
            self.ui_focus_agent = None
        for tier in ["Tier 2", "Tier 3", "Tier 4"]:
            if imgui.selectable(tier, self.ui_focus_agent == tier)[0]:
                self.ui_focus_agent = tier
        imgui.end_combo()
    imgui.same_line()
    if self.ui_focus_agent:
        if imgui.button("x##clear_focus"):
            self.ui_focus_agent = None
    imgui.separator()
    ```
  - **Note**: Tier 1 omitted â€” Tier 1 (Claude Code) never calls `ai_client.send()`, so it produces no comms entries.
  - **How**: Use `Edit`.

- [x] Task 3.3: Add filter logic to `_render_comms_history_panel`. b30e563
  - **Location**: `gui_2.py` `_render_comms_history_panel` (after bleed cleanup, line ~3400). Confirm with `py_get_definition`.
  - **What**: After the `log_to_render = self.prior_session_entries if self.is_viewing_prior_session else list(self._comms_log)` line, add:
    ```python
    if self.ui_focus_agent and not self.is_viewing_prior_session:
        log_to_render = [e for e in log_to_render if e.get("source_tier") == self.ui_focus_agent]
    ```
  - Also add a `source_tier` label in the entry header row (after the `provider/model` text):
    ```python
    tier_label = entry.get("source_tier") or "main"
    imgui.text_colored(C_SUB, f"[{tier_label}]")
    imgui.same_line()
    ```
    Insert this after the `imgui.text_colored(C_LBL, f"{entry.get('provider', '?')}/{entry.get('model', '?')}")` line.
  - **How**: Use `Edit` for each insertion.

- [x] Task 3.4: Add filter logic to `_render_tool_calls_panel`. b30e563
  - **Location**: `gui_2.py:2989`. Confirm with `get_file_slice(2989, 3000)`.
  - **What**: After `imgui.begin_child("scroll_area")` + clipper setup, change the render source:
    - Replace `clipper.begin(len(self._tool_log))` with a pre-filtered list:
      ```python
      tool_log_filtered = self._tool_log if not self.ui_focus_agent else [
          e for e in self._tool_log if e.get("source_tier") == self.ui_focus_agent
      ]
      ```
    - Then `clipper.begin(len(tool_log_filtered))`.
    - Inside the loop use `tool_log_filtered[i_minus_one]` instead of `self._tool_log[i_minus_one]`.
  - **How**: Use `Edit`.

- [x] Task 3.5: Write tests for Phase 3. 6 tests, 18/18 passed. b30e563
  - Test that `ui_focus_agent = "Tier 3"` filters out entries with `source_tier = "Tier 2"`.
  - Run `uv run pytest tests/ -x -q`.

- [x] Task 3.6: Conductor â€” User Manual Verification. UI confirmed by user. b30e563
  - Launch app. Open Operations Hub.
  - Confirm "Focus Agent:" combo appears above tabs with options: All, Tier 2, Tier 3, Tier 4.
  - With "All" selected: all entries show with `[main]` or `[Tier N]` labels in comms history.
  - With "Tier 3" selected: comms history shows only entries tagged `source_tier = "Tier 3"`.
  - Confirm "x" clear button resets to "All".

---

## Phase: Review Fixes
- [x] Task: Apply review suggestions febcf3b
