diff --git a/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/check_changes.py b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/check_changes.py new file mode 100644 index 00000000..2fef1da9 --- /dev/null +++ b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/check_changes.py @@ -0,0 +1,7 @@ +"""Check what changed on the branch vs master.""" +import subprocess +result = subprocess.run(['git', 'log', '--oneline', 'master..HEAD', '--', 'src/'], capture_output=True, text=True) +out = result.stdout.split(chr(10)) +print(f'Changed src/ files: {len(out)}') +for line in out[:20]: + print(line) diff --git a/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/find_diag.py b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/find_diag.py new file mode 100644 index 00000000..5e928fd7 --- /dev/null +++ b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/find_diag.py @@ -0,0 +1,13 @@ +"""Find relevant lines in sloppy.py log.""" +import os +log = 'tests/logs/sloppy_py_test.log' +with open(log, 'rb') as f: + data = f.read() +text = data.decode('utf-8', errors='replace') +out = [] +for line in text.split(chr(10)): + if 'GeminiCliAdapter' in line or 'mock_gemini' in line or 'cmd_list' in line or 'sending' in line.lower() or 'rag' in line.lower(): + out.append(line[:300]) +with open('tests/artifacts/tier2_state/fix_mma_concurrent_tracks_sim_20260627/sloppy_diag3.txt', 'w', encoding='utf-8') as f: + f.write(chr(10).join(out)) +print(f'Wrote {len(out)} lines') diff --git a/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/fix_import.py b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/fix_import.py new file mode 100644 index 00000000..733d7a98 --- /dev/null +++ b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/fix_import.py @@ -0,0 +1,35 @@ +"""Fix the broken import - revert and re-add correctly.""" +import sys + +path = 'src/rag_engine.py' +with open(path, 'rb') as f: + data = f.read() + +# Revert the broken import +old = b'def _get_chromadb():\n global _CHROMADB\n if _CHROMADB is None:\n import shutil\nimport chromadb\n from chromadb.config import Settings' +new = b'def _get_chromadb():\n global _CHROMADB\n if _CHROMADB is None:\n import chromadb\n from chromadb.config import Settings' + +if old not in data: + print('NOT FOUND: broken import') + sys.exit(1) + +data = data.replace(old, new, 1) + +# Now find a good place to add shutil import (at the top of the file, with other stdlib imports) +# Look for existing import lines +import re +imports = list(re.finditer(rb'^(import|from)\s+\w+', data, re.MULTILINE)) +if imports: + # Add shutil import after the last stdlib import + last_import = imports[-1] + insert_pos = last_import.end() + # Find the end of the line + line_end = data.find(b'\n', insert_pos) + if line_end > 0: + new_data = data[:line_end] + b'\nimport shutil' + data[line_end:] + data = new_data + print('Added shutil import after last stdlib import') + +with open(path, 'wb') as f: + f.write(data) +print('OK: import fixed') diff --git a/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/fix_rag_cleanup.py b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/fix_rag_cleanup.py new file mode 100644 index 00000000..4c484b55 --- /dev/null +++ b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/fix_rag_cleanup.py @@ -0,0 +1,50 @@ +"""Fix the test cleanup to also clean the workspace's .slop_cache - CRLF.""" +import sys + +path = 'tests/test_rag_phase4_final_verify.py' +with open(path, 'rb') as f: + data = f.read() + +old = (b' _workspace_root = str(live_gui_workspace.parent if live_gui_workspace else Path.cwd())\r\n' + b' stale_path = Path(_workspace_root) / ".slop_cache"\r\n' + b' if stale_path.exists():\r\n' + b' for col_dir in stale_path.iterdir():\r\n' + b' if col_dir.is_dir() and col_dir.name.startswith("chroma_"):\r\n' + b' try:\r\n' + b' shutil.rmtree(col_dir)\r\n' + b' except Exception:\r\n' + b' pass') + +new = (b' # Clean the chroma cache BEFORE the test starts. The chroma collection is stored\r\n' + b' # in the live_gui_workspace\'s .slop_cache directory (one per test workspace). Prior\r\n' + b' # tests leave collections at this path with a different embedding dimension\r\n' + b' # (e.g. 3072 from a Gemini/OpenAI provider) than the current test\'s local model\r\n' + b' # (384). The RAG engine\'s _validate_collection_dim detects the mismatch and tries\r\n' + b' # to recreate the collection, but on Windows the delete_collection call fails\r\n' + b' # with WinError 32 (file in use) because the prior test\'s subprocess still\r\n' + b' # holds the file lock. Wipe the workspace\'s .slop_cache proactively so the\r\n' + b' # test starts with a clean slate.\r\n' + b' stale_paths = []\r\n' + b' if live_gui_workspace:\r\n' + b' stale_paths.append(Path(live_gui_workspace) / ".slop_cache")\r\n' + b' stale_paths.append(Path(str(live_gui_workspace.parent)) / ".slop_cache")\r\n' + b' else:\r\n' + b' stale_paths.append(Path.cwd() / ".slop_cache")\r\n' + b' for stale_path in stale_paths:\r\n' + b' if stale_path.exists():\r\n' + b' for col_dir in stale_path.iterdir():\r\n' + b' if col_dir.is_dir() and col_dir.name.startswith("chroma_"):\r\n' + b' try:\r\n' + b' shutil.rmtree(col_dir)\r\n' + b' except Exception:\r\n' + b' pass') + +if old not in data: + print('NOT FOUND: anchor') + sys.exit(1) + +data = data.replace(old, new, 1) + +with open(path, 'wb') as f: + f.write(data) +print('OK: test cleanup updated to include workspace .slop_cache') diff --git a/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/fix_rag_dim_check.py b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/fix_rag_dim_check.py new file mode 100644 index 00000000..946c7566 --- /dev/null +++ b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/fix_rag_dim_check.py @@ -0,0 +1,49 @@ +"""Make the dim check robust to file locks on Windows. + +Replace `delete_collection` with `shutil.rmtree(ignore_errors=True)` on the +collection directory. This is more robust to file locks (WinError 32 on +Windows) where the live_gui subprocess holds the file lock. +""" +import sys + +path = 'src/rag_engine.py' +with open(path, 'rb') as f: + data = f.read() + +# Check if shutil is already imported +if b'import shutil' not in data.split(b'\n')[0:50][0:50][0]: + # Add shutil import after the other stdlib imports + old_imports = b'import chromadb' + if old_imports in data: + data = data.replace( + old_imports, + b'import shutil\nimport chromadb', + 1 + ) + print('Added shutil import') + +old = (b' self.client.delete_collection(self.collection.name)\n' + b' self.collection = self.client.get_or_create_collection(name=self.collection.name)\n' + b' return Result(data=None)') + +new = (b' # Per fix_test_rag_phase4_final_verify_diagnosis_20260627: shutil.rmtree with\n' + b' # ignore_errors=True is more robust to file locks (WinError 32 on Windows) where\n' + b' # the live_gui subprocess holds the file lock on the chroma collection. The\n' + b' # original delete_collection call fails on locked files, leaving the collection\n' + b' # in a broken state (dim mismatch) that causes subsequent RAG searches to hang.\n' + b' db_path = os.path.abspath(os.path.join(self.base_dir, ".slop_cache", f"chroma_{self.collection.name}"))\n' + b' if os.path.exists(db_path):\n' + b' shutil.rmtree(db_path, ignore_errors=True)\n' + b' self.client = chromadb.PersistentClient(path=os.path.dirname(db_path))\n' + b' self.collection = self.client.get_or_create_collection(name=self.collection.name)\n' + b' return Result(data=None)') + +if old not in data: + print('NOT FOUND: anchor') + sys.exit(1) + +data = data.replace(old, new, 1) + +with open(path, 'wb') as f: + f.write(data) +print('OK: dim check made robust to file locks') diff --git a/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/list_all_workspaces.py b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/list_all_workspaces.py new file mode 100644 index 00000000..a970064c --- /dev/null +++ b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/list_all_workspaces.py @@ -0,0 +1,5 @@ +"""Check all workspaces.""" +import os +for d in sorted(os.listdir('tests/artifacts')): + if d.startswith('live_gui_workspace'): + print(d) diff --git a/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/list_workspaces.py b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/list_workspaces.py new file mode 100644 index 00000000..dc5e94e6 --- /dev/null +++ b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/list_workspaces.py @@ -0,0 +1,5 @@ +"""Check all workspaces.""" +import os +for d in sorted(os.listdir('tests/artifacts')): + if d.startswith('live_gui_workspace_20260627_17'): + print(d) diff --git a/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/read_log.py b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/read_log.py new file mode 100644 index 00000000..46435f30 --- /dev/null +++ b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/read_log.py @@ -0,0 +1,14 @@ +"""Read sloppy_py_test.log.""" +import os +log = 'tests/logs/sloppy_py_test.log' +if os.path.exists(log): + with open(log, 'rb') as f: + data = f.read() + text = data.decode('utf-8', errors='replace') + lines = text.split(chr(10)) + print(f'Total lines: {len(lines)}') + # Show last 50 lines + for line in lines[-80:]: + print(line[:300]) +else: + print('Log not found') diff --git a/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/read_log_first.py b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/read_log_first.py new file mode 100644 index 00000000..d4a21664 --- /dev/null +++ b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/read_log_first.py @@ -0,0 +1,12 @@ +"""Read first 80 lines of sloppy_py_test.log.""" +import os +log = 'tests/logs/sloppy_py_test.log' +if os.path.exists(log): + with open(log, 'rb') as f: + data = f.read() + text = data.decode('utf-8', errors='replace') + lines = text.split(chr(10)) + for line in lines[:80]: + print(line[:300]) +else: + print('Log not found') diff --git a/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/read_log_safe.py b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/read_log_safe.py new file mode 100644 index 00000000..9aa82003 --- /dev/null +++ b/scripts/tier2/artifacts/fix_mma_concurrent_tracks_sim_20260627/read_log_safe.py @@ -0,0 +1,17 @@ +"""Read sloppy_py_test.log safely.""" +import os +log = 'tests/logs/sloppy_py_test.log' +if os.path.exists(log): + with open(log, 'rb') as f: + data = f.read() + text = data.decode('utf-8', errors='replace') + lines = text.split(chr(10)) + # Find RAG, mock, gemini, sending, error lines + for line in lines: + if any(x in line.lower() for x in ['rag', 'mock', 'gemini', 'sending', 'error', 'warning', 'cmd_list', 'embed', 'chroma', 'dim']): + try: + print(line[:300]) + except UnicodeEncodeError: + print(line[:300].encode('ascii', 'replace').decode('ascii')) +else: + print('Log not found')