conductor(archive): move 4 test-hell lineage tracks to archive/

- workspace_path_finalize_20260609 -> archive/ (precursor track)
- test_infrastructure_hardening_20260609 -> archive/ (main 8-phase track)
- mma_tier_usage_reset_fix_20260610 -> archive/ (4 controller bug fixes)
- rag_phase4_sync_fix_20260610 -> archive/ (RAG dim-mismatch + rag_config reset)

The archive/ directory already existed (71+ archived tracks from
earlier phases). The 4 tracks' state.toml + metadata.json were already
closed in the prior commit. This just relocates the folders to match
the convention referenced in tracks.md.
This commit is contained in:
ed
2026-06-10 20:12:50 -04:00
parent 1ea38ad16b
commit 5d2624526b
23 changed files with 0 additions and 0 deletions
@@ -0,0 +1,6 @@
test_rag_phase4_final_verify.py:20: workspace_dir = Path("tests/artifacts/live_gui_workspace")
test_rag_phase4_stress.py:21: workspace_dir = Path("tests/artifacts/live_gui_workspace")
test_saved_presets_sim.py:14: temp_workspace = Path("tests/artifacts/live_gui_workspace")
test_saved_presets_sim.py:121: temp_workspace = Path("tests/artifacts/live_gui_workspace")
test_tool_presets_sim.py:13: temp_workspace = Path("tests/artifacts/live_gui_workspace")
test_visual_sim_gui_ux.py:79: temp_workspace = Path("tests/artifacts/live_gui_workspace")
@@ -0,0 +1,11 @@
test_api_hook_client_wait_for_project_switch.py:27: mock_make.return_value = {"in_progress": False, "path": "C:/projects/foo.toml", "error": None}
test_api_hook_client_wait_for_project_switch.py:29: result = client.wait_for_project_switch(expected_path="C:/projects/foo.toml", timeout=5.0)
test_api_hook_client_wait_for_project_switch.py:32: assert result["path"] == "C:/projects/foo.toml"
test_api_hook_client_wait_for_project_switch.py:70: mock_make.return_value = {"in_progress": True, "path": "C:/projects/foo.toml", "error": None}
test_api_hook_client_wait_for_project_switch.py:71: result = client.wait_for_project_switch(expected_path="C:/projects/foo.toml", timeout=0.5, poll_interval=0.1)
test_ast_inspector_extended.py:20: app.controller.active_project_path = "C:/projects/test/manual_slop.toml"
test_event_serialization.py:11: base_dir = Path("C:/projects/test")
test_project_switch_persona_preset.py:204: { path = "C:/projects/forth/bootslop/main.c", view_mode = "full" },
test_project_switch_persona_preset.py:205: { path = "C:/projects/Pikuma/ps1/code/gte_hello/hello_gte.c", view_mode = "full" },
test_project_switch_persona_preset.py:215: { path = "C:/projects/gencpp/base/dependencies/timing.cpp", view_mode = "full" },
test_project_switch_persona_preset.py:216: { path = "C:/projects/gencpp/base/dependencies/timing.hpp", view_mode = "full" },
@@ -0,0 +1,62 @@
{
"self_contained": [
"test_ai_settings_layout.py",
"test_api_hook_client_io_pool.py",
"test_api_hook_client_wait_for_project_switch.py",
"test_api_hook_extensions.py",
"test_api_hooks_gui_health_live.py",
"test_api_hooks_project_switch.py",
"test_api_hooks_warmup.py",
"test_auto_switch_sim.py",
"test_batcher.py",
"test_categorizer.py",
"test_command_palette_sim.py",
"test_conductor_api_hook_integration.py",
"test_conftest_smart_watchdog.py",
"test_deepseek_infra.py",
"test_extended_sims.py",
"test_external_editor_gui.py",
"test_fixes_20260517.py",
"test_gui2_parity.py",
"test_gui2_performance.py",
"test_gui_context_presets.py",
"test_gui_performance_requirements.py",
"test_gui_startup_smoke.py",
"test_gui_stress_performance.py",
"test_gui_text_viewer.py",
"test_gui_warmup_indicator.py",
"test_handle_reset_session_clears_project.py",
"test_hooks.py",
"test_live_gui_filedialog_regression.py",
"test_live_gui_integration_v2.py",
"test_live_markdown_render.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_patch_modal_gui.py",
"test_phase6_simulation.py",
"test_phase_3_final_verify.py",
"test_preset_windows_layout.py",
"test_rag_engine.py",
"test_rag_phase4_final_verify.py",
"test_rag_phase4_stress.py",
"test_rag_visual_sim.py",
"test_saved_presets_sim.py",
"test_selectable_ui.py",
"test_system_prompt_sim.py",
"test_task_dag_popout_sim.py",
"test_tool_management_layout.py",
"test_tool_presets_sim.py",
"test_ui_cache_controls_sim.py",
"test_undo_redo_sim.py",
"test_usage_analytics_popout_sim.py",
"test_visual_mma.py",
"test_visual_orchestration.py",
"test_visual_sim_gui_ux.py",
"test_visual_sim_mma_v2.py",
"test_workspace_profiles_sim.py",
"test_z_negative_flows.py"
],
"cross_test_dependent": []
}
@@ -0,0 +1,33 @@
test_ai_settings_layout.py: set_value=1 get_value=0 reset_session=0
test_api_hook_extensions.py: set_value=3 get_value=0 reset_session=1
test_auto_switch_sim.py: set_value=4 get_value=2 reset_session=0
test_command_palette_sim.py: set_value=0 get_value=5 reset_session=1
test_conftest_smart_watchdog.py: set_value=0 get_value=0 reset_session=1
test_deepseek_infra.py: set_value=1 get_value=1 reset_session=0
test_extended_sims.py: set_value=13 get_value=1 reset_session=0
test_gui2_parity.py: set_value=4 get_value=4 reset_session=0
test_gui2_performance.py: set_value=1 get_value=0 reset_session=0
test_gui_context_presets.py: set_value=0 get_value=2 reset_session=0
test_handle_reset_session_clears_project.py: set_value=0 get_value=0 reset_session=14
test_hooks.py: set_value=0 get_value=0 reset_session=2
test_live_gui_filedialog_regression.py: set_value=1 get_value=2 reset_session=0
test_live_gui_integration_v2.py: set_value=2 get_value=0 reset_session=0
test_live_workflow.py: set_value=6 get_value=0 reset_session=0
test_mma_concurrent_tracks_sim.py: set_value=3 get_value=0 reset_session=0
test_mma_concurrent_tracks_stress_sim.py: set_value=3 get_value=0 reset_session=0
test_mma_step_mode_sim.py: set_value=3 get_value=0 reset_session=0
test_rag_phase4_final_verify.py: set_value=9 get_value=5 reset_session=0
test_rag_phase4_stress.py: set_value=11 get_value=5 reset_session=0
test_rag_visual_sim.py: set_value=6 get_value=6 reset_session=0
test_saved_presets_sim.py: set_value=3 get_value=0 reset_session=0
test_selectable_ui.py: set_value=1 get_value=2 reset_session=0
test_system_prompt_sim.py: set_value=5 get_value=9 reset_session=0
test_task_dag_popout_sim.py: set_value=3 get_value=0 reset_session=0
test_tool_presets_sim.py: set_value=2 get_value=0 reset_session=0
test_undo_redo_sim.py: set_value=6 get_value=17 reset_session=0
test_usage_analytics_popout_sim.py: set_value=3 get_value=0 reset_session=0
test_visual_mma.py: set_value=1 get_value=0 reset_session=0
test_visual_orchestration.py: set_value=3 get_value=0 reset_session=0
test_visual_sim_mma_v2.py: set_value=5 get_value=0 reset_session=0
test_workspace_profiles_sim.py: set_value=3 get_value=3 reset_session=0
test_z_negative_flows.py: set_value=9 get_value=0 reset_session=0
@@ -0,0 +1,58 @@
57 test files use live_gui:
test_ai_settings_layout.py
test_api_hook_client_io_pool.py
test_api_hook_client_wait_for_project_switch.py
test_api_hook_extensions.py
test_api_hooks_gui_health_live.py
test_api_hooks_project_switch.py
test_api_hooks_warmup.py
test_auto_switch_sim.py
test_batcher.py
test_categorizer.py
test_command_palette_sim.py
test_conductor_api_hook_integration.py
test_conftest_smart_watchdog.py
test_deepseek_infra.py
test_extended_sims.py
test_external_editor_gui.py
test_fixes_20260517.py
test_gui2_parity.py
test_gui2_performance.py
test_gui_context_presets.py
test_gui_performance_requirements.py
test_gui_startup_smoke.py
test_gui_stress_performance.py
test_gui_text_viewer.py
test_gui_warmup_indicator.py
test_handle_reset_session_clears_project.py
test_hooks.py
test_live_gui_filedialog_regression.py
test_live_gui_integration_v2.py
test_live_markdown_render.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_patch_modal_gui.py
test_phase6_simulation.py
test_phase_3_final_verify.py
test_preset_windows_layout.py
test_rag_engine.py
test_rag_phase4_final_verify.py
test_rag_phase4_stress.py
test_rag_visual_sim.py
test_saved_presets_sim.py
test_selectable_ui.py
test_system_prompt_sim.py
test_task_dag_popout_sim.py
test_tool_management_layout.py
test_tool_presets_sim.py
test_ui_cache_controls_sim.py
test_undo_redo_sim.py
test_usage_analytics_popout_sim.py
test_visual_mma.py
test_visual_orchestration.py
test_visual_sim_gui_ux.py
test_visual_sim_mma_v2.py
test_workspace_profiles_sim.py
test_z_negative_flows.py
@@ -0,0 +1,69 @@
# set_value('ai_input') Audit
## Current Status (as of 2026-06-09)
**Test `tests/test_gui2_parity.py::test_gui2_set_value_hook_works` PASSES in isolation** (4.50s).
Prior report (`rag_work_final_20260609_pm.md`, 2026-06-09) said it was a batch failure. This audit verifies the current state.
## Endpoint code path
### Routing map (src/app_controller.py:1052)
```python
self._settable_fields: Dict[str, str] = {
'ai_input': 'ui_ai_input',
...
}
```
### Handler (src/app_controller.py:554-571)
```python
def _handle_set_value(controller: 'AppController', task: dict):
item = task.get("item")
value = task.get("value")
if item in controller._settable_fields:
attr_name = controller._settable_fields[item]
setattr(controller, attr_name, value)
...
```
### Init state (src/app_controller.py:996)
```python
self.ui_ai_input: str = ""
```
### __getattr__ allowlist (src/app_controller.py:1239)
`ui_ai_input` IS in `_UI_FLAG_DEFAULTS` (so `hasattr()` returns True).
## Expected flow
1. `client.set_value('ai_input', 'hello')` → POST /api/gui with `{"action": "set_value", "item": "ai_input", "value": "hello"}`
2. Endpoint dispatches to `_handle_set_value` (via the action handler map at line 1190)
3. `_handle_set_value` looks up `_settable_fields["ai_input"]``"ui_ai_input"`
4. `setattr(controller, "ui_ai_input", "hello")``controller.ui_ai_input = "hello"`
5. `client.get_value('ai_input')` → POST /api/gui with `{"action": "get_value", "item": "ai_input"}`
6. Returns `controller.ui_ai_input` = `"hello"`
## Actual flow (verified 2026-06-09)
Test PASSES in isolation. Both `set_value` and `get_value` work correctly.
## Prior failure (per rag_work_final_20260609_pm.md)
The prior report (2026-06-09 PM) said:
> `test_gui2_set_value_hook_works` batch failure — `set_value` hook returns `'queued'` but `get_value('ai_input')` returns `''` after 1.5s. Different code path from RAG, pre-existing, not investigated this session per the Deduction Loop rule (2-failure cap). Likely a `setattr` routing issue in `gui_2.py` (same class of bug as the earlier `_UI_FLAG_DEFAULTS` fix).
The commit `bcdc26d0` ("fix(gui): correct __getattr__ to not silently return None for missing ui_ attrs") from the prior session likely fixed the underlying `__getattr__` issue. The test now passes in isolation.
## Remaining risk: BATCH behavior
The test passes in isolation but was reported as a BATCH failure. The batch-vs-isolation gap is the same pattern as the RAG test:
- In isolation, the live_gui subprocess starts FRESH, controller state is clean.
- In batch, state from prior tests may have left a different default for `ui_ai_input` (e.g., a prior test set it to a non-empty value, and the session-scoped fixture didn't reset between tests).
## Recommendation
1. Run the test in the live_gui tier-3 batch to confirm the batch-vs-isolation gap.
2. If batch still fails, the fix is to add `controller.ui_ai_input = ""` to the `_handle_reset_session` method (which is called by `client.reset_session()` in the conftest fixture's `finally` block).
3. Alternatively, the test may need to call `client.reset_session()` at the start to ensure a clean state.
## Files affected
- src/app_controller.py:554 (`_handle_set_value` handler)
- src/app_controller.py:1052 (`_settable_fields` map — already has `ai_input`)
- src/app_controller.py:1239 (`_UI_FLAG_DEFAULTS` — already has `ui_ai_input`)
- src/app_controller.py:_handle_reset_session (potential fix for batch state pollution)
- tests/test_gui2_parity.py:1-50 (the test that exposes the issue)
@@ -0,0 +1,68 @@
# _sync_rag_engine Race Audit
## Setters that trigger sync (direct callers)
- `rag_enabled.setter` (src/app_controller.py:1499)
- `rag_source.setter` (src/app_controller.py:1509)
- `rag_emb_provider.setter` (src/app_controller.py:1519)
- `rag_collection_name.setter` (src/app_controller.py:1557)
- `__init__` when `rag_config.enabled` is True (src/app_controller.py:1844)
## Indirect triggers
- `_rebuild_rag_index` is called from `_sync_rag_engine` itself (line 1481) when engine is empty and `self.files` is non-empty
- `ui_file_paths` setter (line 1576) changes `self.files` but does NOT call `_sync_rag_engine` directly; subsequent `_sync_rag_engine` calls see the new files
## Submit pattern (src/app_controller.py:1460-1490)
```
def _sync_rag_engine(self):
self._set_rag_status("initializing...")
def _task():
try:
from src import rag_engine
engine = rag_engine.RAGEngine(self.rag_config, self.active_project_root)
if engine.embedding_provider is None:
self._set_rag_status("error: RAG embedding provider failed to initialize (e.g. missing dependencies)")
return
with self._rag_engine_lock:
self.rag_engine = engine
if self.rag_engine and self.rag_engine.is_empty() and self.files:
self._rebuild_rag_index()
else:
self._set_rag_status("ready")
except Exception as e:
self._set_rag_status(f"error: {e}")
sys.stderr.write(f"[DEBUG RAG] Failed to sync engine: {e}\n")
sys.stderr.flush()
self.submit_io(_task)
```
## Coalescing mechanism
NONE. Every setter call immediately submits a fresh task to the io_pool. There is no debounce, no token check, no dirty flag.
## Lock
`self._rag_engine_lock` exists (line 1482) but only protects the assignment of `self.rag_engine = engine`. The construction of `RAGEngine(...)` runs WITHOUT the lock, so two tasks can be building engines simultaneously.
## Race scenario
1. Test fires `set_rag_collection_name("name_A")` → submit task T1 to io_pool
2. Test fires `set_rag_enabled(True)` 50ms later → submit task T2 to io_pool
3. T1 starts on io_pool thread #1, starts constructing `RAGEngine(self.rag_config, ...)` with collection_name="name_A"
4. T2 starts on io_pool thread #2, starts constructing `RAGEngine(self.rag_config, ...)` with collection_name="name_B"
5. T1 finishes first, acquires `_rag_engine_lock`, sets `self.rag_engine = engine_A` (collection_name="name_A")
6. T2 finishes, acquires lock, sets `self.rag_engine = engine_B` (collection_name="name_B") ← LAST WRITER WINS
7. Test queries `self.rag_engine.vector_store.collection_name` → gets "name_B" (the most recent setter)
8. But the engine was constructed with whatever the controller's rag_config was AT THE TIME of construction. If `_rebuild_rag_index` was called from T1 with files that exist at the time, but T2's engine_A already had different state...
## Why this is non-deterministic
- T1's engine may have indexed files using its config snapshot
- T2's engine may have indexed DIFFERENT files using ITS config snapshot
- Whichever finishes LAST is the one that survives
- The test may have set `rag_collection_name=A` expecting that to be used; but T2 (which set `rag_enabled=True` later) wins the race, and engine_B has `collection_name=B` not A
## Fix outline (for Phase 4)
1. Add to `__init__`: `self._rag_sync_token: int = 0`, `self._rag_sync_dirty: bool = False`, `self._rag_sync_lock: threading.Lock`
2. In `_sync_rag_engine`: increment token, set dirty=True, submit task with current token
3. In the task: check if token is still current. If not, return early (a newer sync will pick up the changes). If yes, build the engine, check dirty again, if clean return, else loop to pick up new changes.
## Files affected
- src/app_controller.py:1460 (_sync_rag_engine method)
- src/app_controller.py:1037 area (AppController.__init__ state)
- New test: tests/test_sync_rag_engine_coalescing.py (Phase 4 Task 4.1.3)