From 42c42985ee05ea74153848efe269b09b9c501753 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 28 Feb 2026 22:12:57 -0500 Subject: [PATCH] chore(mma): Verify track loading in visual simulation and fix deterministic ID logic --- api_hooks.py | 3 +- .../plan.md | 2 +- .../tracks/track_f253a4571b15/state.toml | 28 +++++++++++++++++++ .../tracks/track_f77123543df0/state.toml | 28 +++++++++++++++++++ gui_2.py | 4 +-- tests/temp_project_history.toml | 2 +- tests/visual_sim_mma_v2.py | 20 +++++++++++-- 7 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 conductor/tracks/track_f253a4571b15/state.toml create mode 100644 conductor/tracks/track_f77123543df0/state.toml diff --git a/api_hooks.py b/api_hooks.py index 9a1e355..7327474 100644 --- a/api_hooks.py +++ b/api_hooks.py @@ -125,7 +125,8 @@ class HookHandler(BaseHTTPRequestHandler): result["mma_status"] = getattr(app, "mma_status", "idle") result["ai_status"] = getattr(app, "ai_status", "idle") result["active_tier"] = getattr(app, "active_tier", None) - result["active_track"] = getattr(app, "active_track", None) + at = getattr(app, "active_track", None) + result["active_track"] = at.id if hasattr(at, "id") else at result["active_tickets"] = getattr(app, "active_tickets", []) result["mma_step_mode"] = getattr(app, "mma_step_mode", False) result["pending_approval"] = (getattr(app, "_pending_mma_approval", None) is not None) or getattr(app, "_pending_ask_dialog", False) diff --git a/conductor/tracks/robust_live_simulation_verification/plan.md b/conductor/tracks/robust_live_simulation_verification/plan.md index da1e37e..0f70306 100644 --- a/conductor/tracks/robust_live_simulation_verification/plan.md +++ b/conductor/tracks/robust_live_simulation_verification/plan.md @@ -6,7 +6,7 @@ ## Phase 2: Epic & Track Verification - [x] Task: Write the simulation routine to trigger a new Epic and verify the Track Browser updates correctly. 605dfc3 -- [~] Task: Verify that selecting a newly generated track successfully loads its initial (empty) state into the DAG visualizer. +- [x] Task: Verify that selecting a newly generated track successfully loads its initial (empty) state into the DAG visualizer. ## Phase 3: DAG & Spawn Interception Verification - [ ] Task: Simulate the "Start Track" action and verify the DAG visualizer populates with tasks. diff --git a/conductor/tracks/track_f253a4571b15/state.toml b/conductor/tracks/track_f253a4571b15/state.toml new file mode 100644 index 0000000..d266cd1 --- /dev/null +++ b/conductor/tracks/track_f253a4571b15/state.toml @@ -0,0 +1,28 @@ +discussion = [] + +[metadata] +id = "track_f253a4571b15" +name = "Mock Goal 2" +status = "todo" +created_at = "2026-02-28T22:12:36.511804" +updated_at = "2026-02-28T22:12:36.511804" + +[[tasks]] +id = "mock-ticket-1" +description = "Mock Ticket 1" +status = "todo" +assigned_to = "unassigned" +context_requirements = [] +depends_on = [] +step_mode = false + +[[tasks]] +id = "mock-ticket-2" +description = "Mock Ticket 2" +status = "todo" +assigned_to = "unassigned" +context_requirements = [] +depends_on = [ + "mock-ticket-1", +] +step_mode = false diff --git a/conductor/tracks/track_f77123543df0/state.toml b/conductor/tracks/track_f77123543df0/state.toml new file mode 100644 index 0000000..20b8620 --- /dev/null +++ b/conductor/tracks/track_f77123543df0/state.toml @@ -0,0 +1,28 @@ +discussion = [] + +[metadata] +id = "track_f77123543df0" +name = "Mock Goal 1" +status = "todo" +created_at = "2026-02-28T22:12:36.494624" +updated_at = "2026-02-28T22:12:36.494624" + +[[tasks]] +id = "mock-ticket-1" +description = "Mock Ticket 1" +status = "todo" +assigned_to = "unassigned" +context_requirements = [] +depends_on = [] +step_mode = false + +[[tasks]] +id = "mock-ticket-2" +description = "Mock Ticket 2" +status = "todo" +assigned_to = "unassigned" +context_requirements = [] +depends_on = [ + "mock-ticket-1", +] +step_mode = false diff --git a/gui_2.py b/gui_2.py index 72247b7..dcf31a0 100644 --- a/gui_2.py +++ b/gui_2.py @@ -2063,6 +2063,8 @@ class App: print(f"Dependency error in track '{title}': {e}") sorted_tickets_data = raw_tickets # 3. Create Track and Ticket objects + from datetime import datetime + now = datetime.now() tickets = [] for t_data in sorted_tickets_data: ticket = Ticket( @@ -2078,8 +2080,6 @@ class App: track = Track(id=track_id, description=title, tickets=tickets) # Initialize track state in the filesystem from models import TrackState, Metadata - from datetime import datetime - now = datetime.now() meta = Metadata(id=track_id, name=title, status="todo", created_at=now, updated_at=now) state = TrackState(metadata=meta, discussion=[], tasks=tickets) project_manager.save_track_state(track_id, state, self.ui_files_base_dir) diff --git a/tests/temp_project_history.toml b/tests/temp_project_history.toml index 9e7eeac..5299480 100644 --- a/tests/temp_project_history.toml +++ b/tests/temp_project_history.toml @@ -10,7 +10,7 @@ auto_add = true [discussions.main] git_commit = "" -last_updated = "2026-02-28T22:08:57" +last_updated = "2026-02-28T22:11:24" history = [ "@2026-02-28T22:02:40\nSystem:\n[PERFORMANCE ALERT] CPU usage high: 83.5%. Please consider optimizing recent changes or reducing load.", "@2026-02-28T22:03:10\nSystem:\n[PERFORMANCE ALERT] CPU usage high: 103.9%. Please consider optimizing recent changes or reducing load.", diff --git a/tests/visual_sim_mma_v2.py b/tests/visual_sim_mma_v2.py index 48e5741..02ff219 100644 --- a/tests/visual_sim_mma_v2.py +++ b/tests/visual_sim_mma_v2.py @@ -47,6 +47,7 @@ def test_mma_complete_lifecycle(live_gui) -> None: # 4. Click 'Accept' to start tracks. client.click('btn_mma_accept_tracks') + time.sleep(5) # Add delay to ensure background thread processes track refresh # 5. Wait for 'tracks' list to populate. tracks_populated = False @@ -70,7 +71,12 @@ def test_mma_complete_lifecycle(live_gui) -> None: tracks_list = status_after_tracks.get('tracks') assert tracks_list is not None and len(tracks_list) > 0, "Tracks list is empty or not found." - track_id_to_load = tracks_list[0]['id'] + track_id_to_load = None + for track in tracks_list: + if 'Mock Goal 1' in track.get('title', ''): + track_id_to_load = track['id'] + break + assert track_id_to_load is not None, "Could not find a track with 'Mock Goal 1' in its title." print(f"Attempting to load track with ID: {track_id_to_load}") # Load the first track @@ -80,7 +86,17 @@ def test_mma_complete_lifecycle(live_gui) -> None: active_track_and_tickets_found = False for _ in range(60): # Poll for up to 60 seconds status = client.get_mma_status() - if status and status.get('active_track') == track_id_to_load and \ + print(f"Polling load status: {status}") + if status and status.get('pending_spawn') is True: + print('[SIM] Worker spawn required. Clicking btn_approve_spawn...') + client.click('btn_approve_spawn') + elif status and status.get('pending_approval') is True: + print('[SIM] Tool approval required. Clicking btn_approve_tool...') + client.click('btn_approve_tool') + + # Updated condition to correctly check active_track ID or value + active_track = status.get('active_track') + if status and ( (isinstance(active_track, dict) and active_track.get('id') == track_id_to_load) or (active_track == track_id_to_load) ) and \ 'active_tickets' in status and len(status['active_tickets']) > 0: active_track_and_tickets_found = True break