Private
Public Access
0
0

artifacts

This commit is contained in:
2026-07-02 19:03:49 -04:00
parent 2b4c6c7a56
commit b9228f3ca4
6 changed files with 467 additions and 0 deletions
@@ -0,0 +1,108 @@
"""Wrap the body of the if (app.active_track or app.active_tickets) and app.node_editor_ctx:
block in render_task_dag_panel with a try/except. To do this without manually
reindenting ~195 lines, we use a Python script that finds the if line, dedents
the body, inserts try/except, and re-indents.
"""
import re
from pathlib import Path
GUI_2 = Path(r"C:\projects\manual_slop_tier2\src\gui_2.py")
text = GUI_2.read_text(encoding="utf-8")
lines = text.splitlines(keepends=True)
# Find the function start
fn_start = None
for i, line in enumerate(lines):
if "def render_task_dag_panel" in line:
fn_start = i
break
if fn_start is None:
raise RuntimeError("render_task_dag_panel not found")
# Find the if (app.active_track or app.active_tickets) and app.node_editor_ctx: line
if_start = None
for i in range(fn_start, len(lines)):
line = lines[i]
stripped = line.lstrip()
if stripped.startswith("if (app.active_track or app.active_tickets)"):
if_start = i
break
if if_start is None:
raise RuntimeError("if not found")
# Find the end of the if block (matching 0-indent next line, or next def)
if_end = None
for i in range(if_start + 1, len(lines)):
line = lines[i]
if line.strip() == "" or line.startswith(" ") or line.startswith("\t"):
continue
# Found a non-indented line that's not blank
if_end = i
break
if if_end is None:
if_end = len(lines)
# Find body bounds (indented lines)
body_start = if_start + 1
while body_start < if_end and lines[body_start].strip() == "":
body_start += 1
# Find actual body end (last indented line before 0-indent)
body_end = body_end = if_end
for i in range(if_end - 1, if_start, -1):
if lines[i].strip() != "":
body_end = i + 1
break
# Get the indentation of the if line
if_indent = len(lines[if_start]) - len(lines[if_start].lstrip())
# Body indent should be if_indent + 2 (next level)
body_indent = if_indent + 2
# Extract body lines (preserve content)
body_lines = lines[body_start:body_end]
# Detent: strip body_indent spaces from each line
detented_body = []
for ln in body_lines:
if ln.strip() == "":
detented_body.append("\n")
elif ln.startswith(" " * body_indent):
detented_body.append(" " + ln[body_indent:])
else:
detented_body.append(ln)
# Re-indent: add body_indent spaces to each line
reindented_body = []
for ln in detented_body:
if ln.strip() == "":
reindented_body.append("\n")
else:
reindented_body.append(" " * (body_indent - 1) + ln)
# Build the new content
new_lines = []
new_lines.append(lines[if_start]) # the if line
new_lines.append(" " * (if_indent + 1) + "try:\n")
for ln in reindented_body:
new_lines.append(ln)
new_lines.append(" " * (if_indent + 1) + "except Exception as dag_err:\n")
new_lines.append(" " * (if_indent + 2) + "# imgui-node-editor can raise ImGui assertions (e.g. Missing PopID) that\n")
new_lines.append(" " * (if_indent + 2) + "# would otherwise kill the ImGui main loop and break every subsequent\n")
new_lines.append(" " * (if_indent + 2) + "# test in the same xdist worker that shares the live_gui subprocess.\n")
new_lines.append(" " * (if_indent + 2) + "if not hasattr(app, '_last_request_errors'): app._last_request_errors = []\n")
new_lines.append(" " * (if_indent + 2) + "app._last_request_errors.append(('render_task_dag_panel.dag_error', dag_err))\n")
# Lines after the if body (0-indent)
for i in range(body_end, if_end):
new_lines.append(lines[i])
# Replace
new_text = "".join(lines[:if_start]) + "".join(new_lines) + "".join(lines[if_end:])
# Write back
GUI_2.write_text(new_text, encoding="utf-8")
print(f"OK: modified if block at line {if_start+1}, body lines {body_end - body_start}")
@@ -0,0 +1,138 @@
"""Verify runtime dock state by monkey-patching and registering a custom callback."""
import sys, time, subprocess, shutil, urllib.request, json
from pathlib import Path
PROJ = Path("C:/projects/manual_slop_tier2")
WORK = PROJ / "tests" / "artifacts" / "diag6_runtime_state"
LOG = PROJ / "tests" / "artifacts" / "diag6_runtime_state.log"
RUNTIME_INI = PROJ / "tests" / "artifacts" / "diag6_runtime_ini.txt"
# Clean
if WORK.exists():
shutil.rmtree(WORK)
WORK.mkdir(parents=True, exist_ok=True)
if LOG.exists():
LOG.unlink()
if RUNTIME_INI.exists():
RUNTIME_INI.unlink()
# Wrapper that registers a custom callback BEFORE the app launches
WRAPPER = PROJ / "tests" / "artifacts" / "diag6_wrapper.py"
WRAPPER.write_text('''
import sys, json
sys.path.insert(0, "C:/projects/manual_slop_tier2")
sys.argv = ["sloppy.py", "--enable-test-hooks"]
# Import imgui and patch save_ini_settings_to_disk to also write to a known file
from imgui_bundle import imgui
_orig_save_disk = imgui.save_ini_settings_to_disk
def _hooked_save_disk(path):
res = _orig_save_disk(path)
try:
mem = imgui.save_ini_settings_to_memory()
with open("C:/projects/manual_slop_tier2/tests/artifacts/diag6_runtime_ini.txt", "w", encoding="utf-8") as f:
f.write(str(mem) if mem else "")
except Exception as e:
with open("C:/projects/manual_slop_tier2/tests/artifacts/diag6_runtime_ini.txt", "w", encoding="utf-8") as f:
f.write(f"ERR: {e}")
return res
imgui.save_ini_settings_to_disk = _hooked_save_disk
# Also patch save_ini_settings_to_memory to capture runtime state
def _hooked_save_mem():
res = imgui.save_ini_settings_to_memory()
try:
with open("C:/projects/manual_slop_tier2/tests/artifacts/diag6_runtime_ini.txt", "w", encoding="utf-8") as f:
f.write(str(res) if res else "")
except Exception:
pass
return res
# Now import app
from src.gui_2 import App as _App
_orig_init = _App.__init__
def _patched_init(self, *a, **kw):
_orig_init(self, *a, **kw)
# Register a custom callback that saves the runtime INI to a known location
self.controller._predefined_callbacks["_diag_save_runtime_ini"] = lambda: _hooked_save_mem()
_App.__init__ = _patched_init
import argparse
from pathlib import Path
from src.paths import initialize_paths
initialize_paths(None)
from src.gui_2 import main as _sloppy_main
_sloppy_main()
''')
# Spawn
print("Launching with patched callback...", flush=True)
proc = subprocess.Popen(
["uv", "run", "python", "-u", str(WRAPPER.absolute())],
stdout=open(LOG, "w"),
stderr=subprocess.STDOUT,
cwd=str(WORK),
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0,
)
ready = False
for i in range(30):
time.sleep(0.5)
try:
urllib.request.urlopen("http://127.0.0.1:8999/status", timeout=1)
ready = True
break
except Exception:
pass
if not ready:
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
print("NO_HOOK", flush=True)
sys.exit(1)
print(f"Hook ready. Waiting 15s for first frame + dock layout to settle...", flush=True)
time.sleep(15)
# Trigger the custom callback to save runtime INI
print("Triggering _diag_save_runtime_ini callback...", flush=True)
try:
req = urllib.request.Request(
"http://127.0.0.1:8999/api/gui",
data=json.dumps({"action": "custom_callback", "callback": "_diag_save_runtime_ini", "args": []}).encode(),
headers={"Content-Type": "application/json"},
method="POST",
)
r = urllib.request.urlopen(req, timeout=5)
print(f" POST response: {r.read().decode()}", flush=True)
except Exception as e:
print(f" POST failed: {e}", flush=True)
time.sleep(2)
# Read runtime INI
if RUNTIME_INI.exists():
runtime_text = RUNTIME_INI.read_text(encoding="utf-8", errors="replace")
print(f"\n=== RUNTIME INI ({len(runtime_text)} bytes) ===", flush=True)
for line in runtime_text.splitlines()[:60]:
print(f" {line}", flush=True)
print("=== END ===", flush=True)
else:
print(f"\nRUNTIME_INI not written to {RUNTIME_INI}", flush=True)
# Compare with bundled
bundled = (PROJ / "layouts" / "default.ini").read_text(encoding="utf-8")
if RUNTIME_INI.exists():
runtime_text = RUNTIME_INI.read_text(encoding="utf-8", errors="replace")
if runtime_text == bundled:
print("\n=> RUNTIME INI == BUNDLED INI (HelloImGui honored the layout)", flush=True)
else:
print("\n=> RUNTIME INI != BUNDLED INI (HelloImGui rebuilt the dock)", flush=True)
# Show diff
bundled_lines = bundled.splitlines()
runtime_lines = runtime_text.splitlines()
print(f" bundled: {len(bundled_lines)} lines", flush=True)
print(f" runtime: {len(runtime_lines)} lines", flush=True)
# Kill
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
time.sleep(1)
@@ -0,0 +1,102 @@
"""Regression test: verify the auto-dock layout actually takes effect at runtime.
Launches sloppy.py, waits for first frame + a few seconds, then triggers
imgui.save_ini_settings_to_disk via custom callback. If HelloImGui honored
the bundled INI's dock structure, the saved INI matches the bundled one.
If HelloImGui rebuilt the dock (because runtime DockSpace ID didn't match
or windows weren't yet created when INI was read), the saved INI differs.
"""
import os, sys, time, subprocess, shutil, json, urllib.request
from pathlib import Path
PROJ = Path("C:/projects/manual_slop_tier2")
WORK = PROJ / "tests" / "artifacts" / "diag5_verify_autodock"
LOG = PROJ / "tests" / "artifacts" / "diag5_verify_autodock.log"
INI_INSTALLED = WORK / "manualslop_layout.ini"
INI_AFTER_SAVE = WORK / "manualslop_layout.ini" # same path, post-save
# Clean workspace
if WORK.exists():
shutil.rmtree(WORK)
WORK.mkdir(parents=True, exist_ok=True)
if LOG.exists():
LOG.unlink()
# Bundle the layout INI for comparison (this is what gets installed)
BUNDLED_INI = (PROJ / "layouts" / "default.ini").read_text(encoding="utf-8")
# Spawn sloppy.py with --enable-test-hooks so we can call API
print("Launching sloppy.py...", flush=True)
proc = subprocess.Popen(
["uv", "run", "python", "-u", str(PROJ / "sloppy.py"), "--enable-test-hooks"],
stdout=open(LOG, "w"),
stderr=subprocess.STDOUT,
cwd=str(WORK),
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0,
)
ready = False
for i in range(30):
time.sleep(0.5)
try:
urllib.request.urlopen("http://127.0.0.1:8999/status", timeout=1)
ready = True
break
except Exception:
pass
if not ready:
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
print("NO_HOOK: hook server never started", flush=True)
sys.exit(1)
print(f"Hook ready, waiting 5s for first frame + dock layout to settle...", flush=True)
time.sleep(5)
# Check that the install wrote the INI
assert INI_INSTALLED.exists(), f"pre-run install did not write INI to {INI_INSTALLED}"
installed_size = INI_INSTALLED.stat().st_size
print(f"Installed INI: {installed_size} bytes at {INI_INSTALLED}", flush=True)
# Now trigger save_ini_settings_to_disk via a custom callback
print("Triggering save_ini_settings_to_disk via custom callback...", flush=True)
# Push a callback that calls imgui.save_ini_settings_to_disk
payload = {
"callback": "_trigger_save_ini",
"args": ["manualslop_layout.ini"]
}
# Try direct POST to /api/gui
try:
req = urllib.request.Request(
"http://127.0.0.1:8999/api/gui",
data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"},
method="POST",
)
r = urllib.request.urlopen(req, timeout=5)
print(f" POST /api/gui response: {r.read().decode()}", flush=True)
except Exception as e:
print(f" POST /api/gui failed: {e}", flush=True)
# Wait for save to complete
time.sleep(2)
# Check the INI after save
if not INI_AFTER_SAVE.exists():
print(f"NO_INI: file not found at {INI_AFTER_SAVE}", flush=True)
else:
after_text = INI_AFTER_SAVE.read_text(encoding="utf-8")
after_size = INI_AFTER_SAVE.stat().st_size
print(f"Post-save INI: {after_size} bytes", flush=True)
print(f"Same as bundled? {after_text == BUNDLED_INI}", flush=True)
# Show first 20 lines of post-save INI
print("\n--- POST-SAVE INI (first 20 lines) ---", flush=True)
for line in after_text.splitlines()[:20]:
print(f" {line}", flush=True)
print("--- END ---", flush=True)
# Kill
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
@@ -0,0 +1,69 @@
"""Check what windows are visible in the runtime via the live_gui fixture."""
import subprocess, time, urllib.request, json, sys
from pathlib import Path
PROJ = Path("C:/projects/manual_slop_tier2")
WORK = PROJ / "tests" / "artifacts" / "diag7_visible"
LOG = PROJ / "tests" / "artifacts" / "diag7_visible.log"
if WORK.exists():
import shutil
shutil.rmtree(WORK)
WORK.mkdir(parents=True, exist_ok=True)
if LOG.exists():
LOG.unlink()
# Spawn
print("Launching...", flush=True)
proc = subprocess.Popen(
["uv", "run", "python", "-u", str(PROJ / "sloppy.py"), "--enable-test-hooks"],
stdout=open(LOG, "w"),
stderr=subprocess.STDOUT,
cwd=str(WORK),
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0,
)
ready = False
for i in range(30):
time.sleep(0.5)
try:
urllib.request.urlopen("http://127.0.0.1:8999/status", timeout=1)
ready = True
break
except Exception:
pass
if not ready:
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
print("NO_HOOK", flush=True)
sys.exit(1)
print(f"Ready, waiting 10s...", flush=True)
time.sleep(10)
# Query /api/gui/state for show_windows
try:
r = urllib.request.urlopen("http://127.0.0.1:8999/api/gui/state", timeout=2)
state = json.loads(r.read().decode())
print(f"\nshow_windows state:", flush=True)
if "show_windows" in state:
for k, v in sorted(state["show_windows"].items()):
print(f" {k}: {v}", flush=True)
except Exception as e:
print(f"ERROR: {e}", flush=True)
# Trigger save_ini to memory to capture runtime state
import json
try:
req = urllib.request.Request(
"http://127.0.0.1:8999/api/gui",
data=json.dumps({"action": "custom_callback", "callback": "noop", "args": []}).encode(),
headers={"Content-Type": "application/json"},
method="POST",
)
urllib.request.urlopen(req, timeout=2)
except: pass
# Kill
subprocess.run(["taskkill", "/F", "/T", "/PID", str(proc.pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
time.sleep(1)
@@ -0,0 +1,23 @@
import json
import subprocess
import sys
result = subprocess.run(
["uv", "run", "python", "scripts/audit_exception_handling.py", "--src", "src", "--json"],
capture_output=True, text=True, cwd=r"C:\projects\manual_slop_tier2",
)
if result.returncode != 0:
print("AUDIT FAILED:", result.stderr[:1000])
sys.exit(1)
data = json.loads(result.stdout)
gui = [f for f in data.get("files", []) if "gui_2" in f.get("filename", "")][0]
broad = [f for f in gui.get("findings", []) if f.get("category") == "INTERNAL_BROAD_CATCH"]
silent = [f for f in gui.get("findings", []) if f.get("category") == "INTERNAL_SILENT_SWALLOW"]
print("BROAD CATCHES:")
for f in broad:
print(f" L{f['line']} {f['context']}")
print("SILENT SWALLOWS:")
for f in silent:
print(f" L{f['line']} {f['context']}")
print(f"TOTAL: {len(broad)} broad, {len(silent)} silent")
@@ -0,0 +1,27 @@
import json
import subprocess
import sys
result = subprocess.run(
["uv", "run", "python", "scripts/audit_exception_handling.py", "--src", "src", "--json"],
capture_output=True, text=True, cwd=r"C:\projects\manual_slop_tier2",
)
data = json.loads(result.stdout)
# Check all categories for the helpers we care about
gui = [f for f in data.get("files", []) if "gui_2" in f.get("filename", "")][0]
all_findings = gui.get("findings", [])
# Group by context
by_context = {}
for f in all_findings:
ctx = f.get("context", "")
by_context.setdefault(ctx, []).append(f)
# Check the existing helper
for ctx in ["_tier_stream_scroll_sync_result", "_tier_stream_scroll_sync_result.dispatcher", "_install_default_layout_if_empty", "_install_default_layout_if_empty_result", "render_tier_stream_panel"]:
print(f"=== {ctx} ===")
findings = by_context.get(ctx, [])
for f in findings:
print(f" L{f['line']} [{f['category']}] {f['kind']}: {f.get('context_extra', '')}")
if not findings:
print(" (no findings)")