# Track: Fix Concurrent MMA Live GUI Tests

## Problem Statement
When starting two MMA tracks concurrently via `btn_mma_start_track`, only ONE worker appears instead of two. The test `test_mma_concurrent_tracks_stress_sim.py` correctly identifies this bug.

## Bugs Found (Multiple Layers)

### Bug 1: `self.engine` Single Reference (FIXED - commit ac0b564)
**Root Cause:** `self.engine` was a single ConductorEngine attribute. When second track started, it overwrote `self.engine`, orphaning first track's engine.

**Fix:** Changed to `self.engines: Dict[str, ConductorEngine]` keyed by track.id.

### Bug 2: `active_tickets` Not Initialized (FIXED - commit 6f2a2c2)
**Root Cause:** `AppController.init_state()` never initialized `self.active_tickets`. When GUI tried to render `_render_mma_dashboard()`, `__getattr__` delegation returned `controller.active_tickets` but it didn't exist, causing `AttributeError: 'App' object has no attribute 'active_tickets'`.

**Fix:** Added `self.active_tickets = []` in `init_state()`.

### Bug 3: `_start_track_logic` Uses `self.active_track.id` When None (FIXED - commit f3585cb)
**Root Cause:** `_cb_accept_tracks` calls `_start_track_logic` in a loop for each proposed track. `_start_track_logic` used `self.engines[self.active_track.id]` but `self.active_track` was None (only set by `_cb_load_track`, not by accept logic).

**Fix:** Changed to `self.engines[track.id]` using the locally created track object.

### Bug 4: `_cb_start_track` Overwrites `active_track` (PARTIALLY FIXED - commit b0a837d)
**Root Cause:** When `btn_mma_start_track(track_a_id)` is called:
1. `_cb_load_track(track_a_id)` is called - may fail if track not saved to disk
2. If fails, `self.active_track` remains None or pointing to wrong track
3. When `btn_mma_start_track(track_b_id)` is called next, it overwrites `self.active_track` to track B
4. Engine for track A never created properly

**Fix:** Added explicit reload path when loaded track doesn't match requested track.

## Current Status
After fixes 1-4, the log shows:
- Track A: `_cb_start_track` called, load fails, reload path triggered but track A worker never visible
- Track B: Works correctly, worker appears
- Test assertion: `seen_a=False, seen_b=True`

## Remaining Issue
The reload path in `_cb_start_track` (commit b0a837d) correctly identifies that load failed, but the reload itself may not be working. Need to verify:
1. `_cb_load_track(track_a_id)` is called with correct track ID
2. Track state is properly saved and can be loaded
3. `active_track` is correctly set after reload

## Architecture Notes

### API Flow for Starting Tracks
```
test clicks btn_mma_start_track(track_a_id)
  → api_hook_client.click('btn_mma_start_track', user_data=track_a_id)
  → POST /api/gui {"action": "click", "item": "btn_mma_start_track", "user_data": track_a_id}
  → _process_gui_task finds btn_mma_start_track in _clickable_actions
  → calls _cb_start_track(user_data=track_a_id)
    → calls _cb_load_track(track_id)
    → loads track state from disk
    → sets self.active_track
    → creates ConductorEngine
    → stores in self.engines[track_id]
    → starts engine thread
```

### Key Files
- `src/app_controller.py` - Contains all the bugs and fixes
- `src/multi_agent_conductor.py` - ConductorEngine, run loop
- `src/api_hooks.py` - API endpoint routing
- `src/gui_2.py` - UI rendering, `__getattr__` delegation
- `tests/test_mma_concurrent_tracks_sim.py` - The failing test

## Success Criteria
- [x] GUI starts without crash (active_tickets initialized)
- [x] `self.engines` dict properly stores multiple concurrent engines
- [ ] Two concurrent tracks produce two concurrent workers visible in `get_mma_workers()`
- [ ] No regression in single-track execution
- [ ] All concurrent tests pass