artifacts

This commit is contained in:
ed
2026-06-26 06:12:02 -04:00
parent 8f6ae6d983
commit 0a65056fc5
28 changed files with 1227 additions and 7 deletions
@@ -0,0 +1,39 @@
"""Add EMPTY_TEXT_EDITOR_CONFIG after the ExternalEditorConfig class."""
from pathlib import Path
PATH = Path(r"C:\projects\manual_slop_tier2\src\models.py")
content = PATH.read_text(encoding="utf-8")
# Add EMPTY_TEXT_EDITOR_CONFIG after ExternalEditorConfig class
old = """ editors = {}
for name, ed_data in data.get(\"editors\", {}).items():
if isinstance(ed_data, dict): editors[name] = TextEditorConfig.from_dict(ed_data)
elif isinstance(ed_data, str): editors[name] = TextEditorConfig(name=name, path=ed_data)
return cls(editors=editors, default_editor=data.get(\"default_editor\"))
#region: Persona"""
new = """ editors = {}
for name, ed_data in data.get(\"editors\", {}).items():
if isinstance(ed_data, dict): editors[name] = TextEditorConfig.from_dict(ed_data)
elif isinstance(ed_data, str): editors[name] = TextEditorConfig(name=name, path=ed_data)
return cls(editors=editors, default_editor=data.get(\"default_editor\"))
EMPTY_TEXT_EDITOR_CONFIG: TextEditorConfig = TextEditorConfig()
#region: Persona"""
if old in content:
content = content.replace(old, new)
print("Added EMPTY_TEXT_EDITOR_CONFIG sentinel")
else:
print("Pattern not found, adding after from_dict method instead")
# Try simpler insertion
old2 = ' return cls(editors=editors, default_editor=data.get("default_editor"))\n'
new2 = old2 + '\n\nEMPTY_TEXT_EDITOR_CONFIG: TextEditorConfig = TextEditorConfig()\n'
content = content.replace(old2, new2, 1)
print("Inserted via simpler replacement")
PATH.write_text(content, encoding="utf-8")
@@ -0,0 +1,47 @@
"""Test what breaks if we change Metadata from dict[str, Any] to a dataclass."""
import subprocess
from pathlib import Path
REPO = Path(r"C:\projects\manual_slop_tier2")
# Find sites that use Metadata["key"] or Metadata.get("key")
import os
env = os.environ.copy()
env["GIT_PAGER"] = "cat"
# Test 1: count Metadata["key"] usages
cmd = ["git", "grep", "-cE", "-e", r"Metadata\[['\"]", "--", "src/*.py"]
r = subprocess.run(cmd, cwd=str(REPO), capture_output=True, text=True, encoding="utf-8", env=env)
print(f"Metadata['key'] usages:")
total = 0
for line in r.stdout.splitlines():
if ":" in line:
n = int(line.split(":")[-1])
total += n
print(f" {n:3d} {line.split(':')[0]}")
print(f" TOTAL: {total}")
print()
# Test 2: count Metadata.get("key", ...) usages
cmd = ["git", "grep", "-cE", "-e", r"Metadata\.get\(['\"]", "--", "src/*.py"]
r = subprocess.run(cmd, cwd=str(REPO), capture_output=True, text=True, encoding="utf-8", env=env)
print(f"Metadata.get('key', ...) usages:")
total = 0
for line in r.stdout.splitlines():
if ":" in line:
n = int(line.split(":")[-1])
total += n
print(f" {n:3d} {line.split(':')[0]}")
print(f" TOTAL: {total}")
print()
# Test 3: count Metadata usages that would NOT break (just attribute or pass-through)
cmd = ["git", "grep", "-cE", "-e", r"\bMetadata\b", "--", "src/*.py"]
r = subprocess.run(cmd, cwd=str(REPO), capture_output=True, text=True, encoding="utf-8", env=env)
print(f"Total Metadata usages (incl. typing):")
total = 0
for line in r.stdout.splitlines():
if ":" in line:
n = int(line.split(":")[-1])
total += n
print(f" TOTAL: {total}")
@@ -0,0 +1,83 @@
#region: Project Context (Phase 2 dataclasses for cruft_elimination_20260627)
@dataclass(frozen=True, slots=True)
class ProjectMeta:
name: str = ""
summary_only: bool = False
execution_mode: str = "standard"
@dataclass(frozen=True, slots=True)
class ProjectOutput:
namespace: str = "project"
output_dir: str = ""
@dataclass(frozen=True, slots=True)
class ProjectFiles:
base_dir: str = ""
paths: tuple[str, ...] = ()
@dataclass(frozen=True, slots=True)
class ProjectScreenshots:
base_dir: str = "."
paths: tuple[str, ...] = ()
@dataclass(frozen=True, slots=True)
class ProjectDiscussion:
roles: tuple[str, ...] = ()
history: tuple[str, ...] = ()
@dataclass(frozen=True, slots=True)
class ProjectContext:
"""Typed return type for project_manager.flat_config().
Replaces the dict[str, Any] that flat_config() returned.
Per conductor/tracks/cruft_elimination_20260627/SPEC_CORRECTION_phase_2.md."""
project: ProjectMeta = field(default_factory=ProjectMeta)
output: ProjectOutput = field(default_factory=ProjectOutput)
files: ProjectFiles = field(default_factory=ProjectFiles)
screenshots: ProjectScreenshots = field(default_factory=ProjectScreenshots)
context_presets: Metadata = field(default_factory=dict)
discussion: ProjectDiscussion = field(default_factory=ProjectDiscussion)
def to_dict(self) -> Metadata:
return {
"project": {
"name": self.project.name,
"summary_only": self.project.summary_only,
"execution_mode": self.project.execution_mode,
},
"output": {
"namespace": self.output.namespace,
"output_dir": self.output.output_dir,
},
"files": {
"base_dir": self.files.base_dir,
"paths": list(self.files.paths),
},
"screenshots": {
"base_dir": self.screenshots.base_dir,
"paths": list(self.screenshots.paths),
},
"context_presets": dict(self.context_presets),
"discussion": {
"roles": list(self.discussion.roles),
"history": list(self.discussion.history),
},
}
def __getitem__(self, key: str) -> Any:
return self.to_dict()[key]
def get(self, key: str, default: Any = None) -> Any:
return self.to_dict().get(key, default)
EMPTY_PROJECT_CONTEXT: ProjectContext = ProjectContext()
#endregion: Project Context
@@ -0,0 +1,16 @@
"""Check what FileItemsDiff looks like."""
from typing import get_type_hints
from src import type_aliases
print("FileItemsDiff._fields =", type_aliases.FileItemsDiff._fields)
try:
hints = get_type_hints(type_aliases.FileItemsDiff)
print("hints =", hints)
except Exception as e:
print(f"get_type_hints failed: {e}")
# Try with globalns
try:
hints = get_type_hints(type_aliases.FileItemsDiff, globalns={"models": __import__("src.models", fromlist=["FileItem"])})
print("with globalns hints =", hints)
except Exception as e:
print(f"with globalns failed: {e}")
@@ -0,0 +1,20 @@
"""Update diff_viewer: replace `return None` with `return (-1, -1, -1, -1)` in parse_hunk_header."""
from pathlib import Path
PATH = Path(r"C:\projects\manual_slop_tier2\src\diff_viewer.py")
content = PATH.read_text(encoding="utf-8")
# Find the parse_hunk_header function body and replace return None
old_lines = [
" if not line.startswith(\"@@\"): return None\n",
" if len(parts) < 2: return None\n",
]
new_lines = [
" if not line.startswith(\"@@\"): return (-1, -1, -1, -1)\n",
" if len(parts) < 2: return (-1, -1, -1, -1)\n",
]
for old, new in zip(old_lines, new_lines):
count = content.count(old)
if count:
content = content.replace(old, new)
print(f" Replaced {count}x")
PATH.write_text(content, encoding="utf-8")
@@ -0,0 +1,15 @@
"""Update test_external_editor.py for Optional removal."""
from pathlib import Path
PATH = Path(r"C:\projects\manual_slop_tier2\tests\test_external_editor.py")
content = PATH.read_text(encoding="utf-8")
content = content.replace(
" assert config.get_default() is None\n",
" assert config.get_default().name == \"\"\n",
)
content = content.replace(
" assert editor is None\n",
" assert editor.name == \"\"\n",
)
PATH.write_text(content, encoding="utf-8")
print("Updated test_external_editor.py")
@@ -0,0 +1,58 @@
"""Convert all Optional[tree_sitter.Node] in file_cache.py to tree_sitter.Node (returns root on not-found)."""
from pathlib import Path
PATH = Path(r"C:\projects\manual_slop_tier2\src\file_cache.py")
content = PATH.read_text(encoding="utf-8")
# Change return type and return None to return node
old_types = [
" def walk(node: tree_sitter.Node, target_parts: List[str]) -> Optional[tree_sitter.Node]:",
" def deep_search(node: tree_sitter.Node, target: str) -> Optional[tree_sitter.Node]:",
]
new_types = [
" def walk(node: tree_sitter.Node, target_parts: List[str]) -> tree_sitter.Node:",
" def deep_search(node: tree_sitter.Node, target: str) -> tree_sitter.Node:",
]
for old, new in zip(old_types, new_types):
count = content.count(old)
content = content.replace(old, new)
print(f" {count}x: {old[:60]}")
# Walk function returns: search for `return None` within walk/deep_search functions
# These functions return at:
# - `if not target_parts: return None` -> return node (root, sentinel)
# - `return None` (last line of walk)
# - In deep_search: `if not found_node or alt...` checks
# Easier: replace `return None` -> `return node` in these functions
# Find the walk functions and deep_search functions, replace return None with return node
# Use regex to be safe
import re
# Match `return None` lines within the walk/deep_search function bodies
# Since they're nested, we can do a targeted replace per function definition
# Pattern: def walk(...): ... return None -> replace with return node
# Pattern: def deep_search(...): ... return None -> replace with return node
# Find each walk function body and replace
walk_pattern = re.compile(
r"( def walk\(node: tree_sitter\.Node, target_parts: List\[str\]\) -> tree_sitter\.Node:\n.*?)( def |class |#end)",
re.DOTALL,
)
for match in walk_pattern.finditer(content):
body = match.group(1)
new_body = body.replace("return None", "return node")
content = content.replace(body, new_body, 1)
deep_pattern = re.compile(
r"( def deep_search\(node: tree_sitter\.Node, target: str\) -> tree_sitter\.Node:\n.*?)( def |class |#end)",
re.DOTALL,
)
for match in deep_pattern.finditer(content):
body = match.group(1)
new_body = body.replace("return None", "return node")
content = content.replace(body, new_body, 1)
PATH.write_text(content, encoding="utf-8")
print("Updated file_cache.py")
@@ -0,0 +1,22 @@
"""Fix fuzzy_anchor.py - replace remaining `return None` with `return (-1, -1)`."""
from pathlib import Path
PATH = Path(r"C:\projects\manual_slop_tier2\src\fuzzy_anchor.py")
content = PATH.read_text(encoding="utf-8")
replacements = [
("if not start_ctx or not end_ctx: return None", "if not start_ctx or not end_ctx: return (-1, -1)"),
("if best_s == -1: return None", "if best_s == -1: return (-1, -1)"),
(" return None\n", " return (-1, -1)\n"),
]
for old, new in replacements:
count = content.count(old)
if count:
content = content.replace(old, new)
print(f" Replaced {count}x: {old[:50]!r}")
else:
print(f" NOT FOUND: {old[:50]!r}")
PATH.write_text(content, encoding="utf-8")
print(f"Updated {PATH}")
@@ -0,0 +1,12 @@
"""Update fuzzy_anchor tests: `is None` -> `== (-1, -1)`."""
from pathlib import Path
PATH = Path(r"C:\projects\manual_slop_tier2\tests\test_fuzzy_anchor.py")
content = PATH.read_text(encoding="utf-8")
old1 = " assert result is None\n"
new1 = " assert result == (-1, -1)\n"
content = content.replace(old1, new1)
PATH.write_text(content, encoding="utf-8")
print("Updated test_fuzzy_anchor.py")
@@ -0,0 +1,15 @@
"""Convert Optional[threading.Thread] -> threading.Thread with sentinel."""
from pathlib import Path
PATH = Path(r"C:\projects\manual_slop_tier2\src\multi_agent_conductor.py")
content = PATH.read_text(encoding="utf-8")
content = content.replace(
"def spawn(self, ticket_id: str, target: Callable, args: tuple) -> Optional[threading.Thread]:",
"def spawn(self, ticket_id: str, target: Callable, args: tuple) -> threading.Thread:"
)
content = content.replace(
" if len(self._active) >= self.max_workers:\n return None",
" if len(self._active) >= self.max_workers:\n return threading.Thread() # sentinel: empty thread, not started"
)
PATH.write_text(content, encoding="utf-8")
print("Updated multi_agent_conductor.py")
@@ -0,0 +1,10 @@
"""Update test_parallel_execution: `t3 is None` -> `not t3.is_alive()`."""
from pathlib import Path
PATH = Path(r"C:\projects\manual_slop_tier2\tests\test_parallel_execution.py")
content = PATH.read_text(encoding="utf-8")
old = " assert t3 is None\n assert pool.get_active_count() == 2\n"
new = " assert not t3.is_alive()\n assert pool.get_active_count() == 2\n"
content = content.replace(old, new)
PATH.write_text(content, encoding="utf-8")
print("Updated test_parallel_execution.py")
@@ -0,0 +1,8 @@
"""Fix patch_modal.py - replace _pending_patch = None with EMPTY_PATCH."""
from pathlib import Path
PATH = Path(r"C:\projects\manual_slop_tier2\src\patch_modal.py")
content = PATH.read_text(encoding="utf-8")
content = content.replace("self._pending_patch = None", "self._pending_patch = EMPTY_PATCH")
PATH.write_text(content, encoding="utf-8")
print("Updated patch_modal.py")
@@ -0,0 +1,11 @@
"""Update patch_modal tests: get_pending_patch() is None -> == EMPTY_PATCH."""
from pathlib import Path
PATH = Path(r"C:\projects\manual_slop_tier2\tests\test_patch_modal.py")
content = PATH.read_text(encoding="utf-8")
old = " assert manager.get_pending_patch() is None\n"
new = " assert manager.get_pending_patch().patch_text == \"\"\n"
count = content.count(old)
content = content.replace(old, new)
PATH.write_text(content, encoding="utf-8")
print(f"Replaced {count} occurrences")
@@ -0,0 +1,19 @@
"""Quick fix for test_summary_cache.py - replace all `is None` with `== ""`."""
from pathlib import Path
PATH = Path(r"C:\projects\manual_slop_tier2\tests\test_summary_cache.py")
content = PATH.read_text(encoding="utf-8")
content = content.replace(
'assert cache.get_summary(file_path, content_hash) is None',
'assert cache.get_summary(file_path, content_hash) == ""'
)
content = content.replace(
'assert cache.get_summary(file_path, "different_hash") is None',
'assert cache.get_summary(file_path, "different_hash") == ""'
)
content = content.replace(
'assert cache.get_summary("file3.py", "hash3") is None',
'assert cache.get_summary("file3.py", "hash3") == ""'
)
PATH.write_text(content, encoding="utf-8")
print("Updated test_summary_cache.py")
@@ -0,0 +1,69 @@
"""Phase 2 verification: flat_config returns ProjectContext."""
from src.project_manager import flat_config
from src.models import ProjectContext, ProjectMeta, ProjectOutput, ProjectFiles, ProjectScreenshots, ProjectDiscussion
# Test 1: empty dict input
ctx = flat_config({})
assert isinstance(ctx, ProjectContext)
assert isinstance(ctx.project, ProjectMeta)
assert isinstance(ctx.output, ProjectOutput)
assert isinstance(ctx.files, ProjectFiles)
assert isinstance(ctx.screenshots, ProjectScreenshots)
assert isinstance(ctx.discussion, ProjectDiscussion)
assert ctx.project.name == ""
assert ctx.output.output_dir == ""
assert ctx.files.paths == ()
assert ctx.screenshots.base_dir == "."
assert ctx.screenshots.paths == ()
assert ctx.discussion.roles == ()
assert ctx.discussion.history == ()
print("Test 1 OK: empty dict -> ProjectContext with zero defaults")
# Test 2: full dict input
proj = {
"project": {"name": "test-proj", "summary_only": True, "execution_mode": "fast"},
"output": {"namespace": "ns1", "output_dir": "/tmp/out"},
"files": {"base_dir": "/src", "paths": ["a.py", "b.py"]},
"screenshots": {"base_dir": "/scr", "paths": ["s1.png"]},
"context_presets": {"p1": {"name": "p1"}},
"discussion": {
"active": "main",
"roles": ["User", "AI"],
"discussions": {"main": {"history": ["msg1", "msg2"]}},
},
}
ctx = flat_config(proj, disc_name="main")
assert ctx.project.name == "test-proj"
assert ctx.project.summary_only is True
assert ctx.project.execution_mode == "fast"
assert ctx.output.namespace == "ns1"
assert ctx.output.output_dir == "/tmp/out"
assert ctx.files.base_dir == "/src"
assert ctx.files.paths == ("a.py", "b.py")
assert ctx.screenshots.base_dir == "/scr"
assert ctx.screenshots.paths == ("s1.png",)
assert ctx.discussion.roles == ("User", "AI")
assert ctx.discussion.history == ("msg1", "msg2")
print("Test 2 OK: full dict input -> correct dataclass fields")
# Test 3: dict-compat methods
assert ctx.get("files") == {"base_dir": "/src", "paths": ["a.py", "b.py"]}
assert ctx["output"] == {"namespace": "ns1", "output_dir": "/tmp/out"}
assert ctx.get("missing", "default") == "default"
print("Test 3 OK: dict-compat __getitem__ / get work")
# Test 4: to_dict() round-trip
d = ctx.to_dict()
assert d["project"]["name"] == "test-proj"
assert d["output"]["output_dir"] == "/tmp/out"
assert d["files"]["paths"] == ["a.py", "b.py"]
assert d["discussion"]["roles"] == ["User", "AI"]
assert d["context_presets"] == {"p1": {"name": "p1"}}
print("Test 4 OK: to_dict() round-trip preserves data")
# Test 5: EMPTY_PROJECT_CONTEXT sentinel
from src.models import EMPTY_PROJECT_CONTEXT
assert isinstance(EMPTY_PROJECT_CONTEXT, ProjectContext)
print("Test 5 OK: EMPTY_PROJECT_CONTEXT sentinel exists")
print("\nAll 5 Phase 2 verification tests PASS.")
@@ -0,0 +1,91 @@
"""Phase 3 follow-up: remove all hasattr(f, ...) defensive checks in gui_2.py.
self.files and self.context_files are GUARANTEED List[FileItem] per the
init code at gui_2.py:869-873 + app_controller.py:1996-2005.
"""
from pathlib import Path
# Pattern -> Replacement (use exact byte matches)
# All sites confirmed to be on `self.files` or `self.context_files` which are List[FileItem]
EDITS = [
# Block 1: lines 371-376 (init-style unpack with multiple hasattr checks)
(
" p = f.path if hasattr(f, 'path') else str(f)\n"
" vm = f.view_mode if hasattr(f, 'view_mode') else 'summary'\n"
" slc = copy.deepcopy(f.custom_slices) if hasattr(f, 'custom_slices') else []\n"
" msk = copy.deepcopy(f.ast_mask) if hasattr(f, 'ast_mask') else {}\n"
" sig = f.ast_signatures if hasattr(f, 'ast_signatures') else False\n"
" dfn = f.ast_definitions if hasattr(f, 'ast_definitions') else False\n",
" p = f.path\n"
" vm = f.view_mode\n"
" slc = copy.deepcopy(f.custom_slices)\n"
" msk = copy.deepcopy(f.ast_mask)\n"
" sig = f.ast_signatures\n"
" dfn = f.ast_definitions\n",
),
# Line 842: files = [f.to_dict() if hasattr(f, 'to_dict') else f for f in self.files]
(
" files = [f.to_dict() if hasattr(f, 'to_dict') else f for f in self.files],\n",
" files = [f.to_dict() for f in self.files],\n",
),
# Line 843: context_files = [f.to_dict() if hasattr(f, 'to_dict') else f for f in self.context_files]
(
" context_files = [f.to_dict() if hasattr(f, 'to_dict') else f for f in self.context_files],\n",
" context_files = [f.to_dict() for f in self.context_files],\n",
),
# Lines 980-981
(
" fi.custom_slices = copy.deepcopy(f.custom_slices) if hasattr(f, 'custom_slices') else []\n"
" fi.ast_mask = copy.deepcopy(f.ast_mask) if hasattr(f, 'ast_mask') else {}\n",
" fi.custom_slices = copy.deepcopy(f.custom_slices)\n"
" fi.ast_mask = copy.deepcopy(f.ast_mask)\n",
),
# Line 997
(
" return [f.path if hasattr(f, 'path') else str(f) for f in self.files]\n",
" return [f.path for f in self.files]\n",
),
# Line 1003
(
" old_files = {f.path: f for f in self.files if hasattr(f, 'path')}\n",
" old_files = {f.path: f for f in self.files}\n",
),
# Line 1315
(
" f_path = f.path if hasattr(f, \"path\") else str(f)\n",
" f_path = f.path\n",
),
# Line 3669
(
" app.files.sort(key=lambda f: f.path.lower() if hasattr(f, 'path') else str(f).lower())\n",
" app.files.sort(key=lambda f: f.path.lower())\n",
),
# Line 3722
(
" if p not in [f.path if hasattr(f, \"path\") else f for f in app.files]: app.files.append(models.FileItem(path=p))\n",
" if p not in [f.path for f in app.files]: app.files.append(models.FileItem(path=p))\n",
),
# Line 3727
(
" existing = {f.path if hasattr(f, \"path\") else str(f) for f in app.files}\n",
" existing = {f.path for f in app.files}\n",
),
# Lines 3773, 3778, 3788, 3797 - need to check uniqueness before replacement
# Will use line-by-line approach with sed-like replacement
]
REPO = Path(r"C:\projects\manual_slop_tier2\gui_2.py") # placeholder
GUI_2 = REPO.parent / "src" / "gui_2.py"
content = GUI_2.read_text(encoding="utf-8")
original_len = len(content)
for i, (old, new) in enumerate(EDITS):
if old in content:
content = content.replace(old, new, 1)
print(f" Edit {i+1}: applied")
else:
print(f" Edit {i+1}: NOT FOUND")
GUI_2.write_text(content, encoding="utf-8")
print(f"\nFile length: {original_len} -> {len(content)} (delta {len(content) - original_len})")
print(f"Path: {GUI_2}")
@@ -0,0 +1,105 @@
"""Phase 3 follow-up batch 2: remaining hasattr checks in gui_2.py.
Different indentation patterns and 'f' variable context.
"""
from pathlib import Path
GUI_2 = Path(r"C:\projects\manual_slop_tier2\src\gui_2.py")
# (old, new) pairs - line-specific replacements
EDITS = [
# Line 3773, 3778, 3788, 3797 - duplicates with leading 4-space indent
(
" f_path = f.path if hasattr(f, \"path\") else str(f)\n",
" f_path = f.path\n",
),
(
" f_path = f.path if hasattr(f, \"path\") else str(f)\n",
" f_path = f.path\n",
),
# Line 3786: context_paths = {f.path if hasattr(f, "path") else str(f) for f in app.context_files}
(
" context_paths = {f.path if hasattr(f, \"path\") else str(f) for f in app.context_files}\n",
" context_paths = {f.path for f in app.context_files}\n",
),
# Line 3840
(
" fpath = f.path if hasattr(f, 'path') else str(f)\n",
" fpath = f.path\n",
),
# Lines 4367-4372: another block (5-space indent)
(
" p = f.path if hasattr(f, 'path') else str(f)\n"
" vm = f.view_mode if hasattr(f, 'view_mode') else 'summary'\n"
" slc = copy.deepcopy(f.custom_slices) if hasattr(f, 'custom_slices') else []\n"
" msk = copy.deepcopy(f.ast_mask) if hasattr(f, 'ast_mask') else {}\n"
" sig = f.ast_signatures if hasattr(f, 'ast_signatures') else False\n"
" dfn = f.ast_definitions if hasattr(f, 'ast_definitions') else False\n",
" p = f.path\n"
" vm = f.view_mode\n"
" slc = copy.deepcopy(f.custom_slices)\n"
" msk = copy.deepcopy(f.ast_mask)\n"
" sig = f.ast_signatures\n"
" dfn = f.ast_definitions\n",
),
# Line 4393
(
" path = f.path if hasattr(f, \"path\") else str(f)\n",
" path = f.path\n",
),
# Lines 4407-4412: 6-space indent block
(
" p = f.path if hasattr(f, 'path') else str(f)\n"
" vm = f.view_mode if hasattr(f, 'view_mode') else 'summary'\n"
" slc = copy.deepcopy(f.custom_slices) if hasattr(f, 'custom_slices') else []\n"
" msk = copy.deepcopy(f.ast_mask) if hasattr(f, 'ast_mask') else {}\n"
" sig = f.ast_signatures if hasattr(f, 'ast_signatures') else False\n"
" dfn = f.ast_definitions if hasattr(f, 'ast_definitions') else False\n",
" p = f.path\n"
" vm = f.view_mode\n"
" slc = copy.deepcopy(f.custom_slices)\n"
" msk = copy.deepcopy(f.ast_mask)\n"
" sig = f.ast_signatures\n"
" dfn = f.ast_definitions\n",
),
# Lines 4542-4547: 4-space indent block
(
" p = f.path if hasattr(f, 'path') else str(f)\n"
" vm = f.view_mode if hasattr(f, 'view_mode') else 'summary'\n"
" slc = copy.deepcopy(f.custom_slices) if hasattr(f, 'custom_slices') else []\n"
" msk = copy.deepcopy(f.ast_mask) if hasattr(f, 'ast_mask') else {}\n"
" sig = f.ast_signatures if hasattr(f, 'ast_signatures') else False\n"
" dfn = f.ast_definitions if hasattr(f, 'ast_definitions') else False\n",
" p = f.path\n"
" vm = f.view_mode\n"
" slc = copy.deepcopy(f.custom_slices)\n"
" msk = copy.deepcopy(f.ast_mask)\n"
" sig = f.ast_signatures\n"
" dfn = f.ast_definitions\n",
),
# Lines 4565-4567: 2-space indent block
(
" p = f.path if hasattr(f, 'path') else str(f)\n"
" vm = f.view_mode if hasattr(f, 'view_mode') else 'summary'\n"
" agg = f.auto_aggregate if hasattr(f, 'auto_aggregate') else False\n",
" p = f.path\n"
" vm = f.view_mode\n"
" agg = f.auto_aggregate\n",
),
]
content = GUI_2.read_text(encoding="utf-8")
original_len = len(content)
for i, (old, new) in enumerate(EDITS):
count = content.count(old)
if count == 1:
content = content.replace(old, new, 1)
print(f" Edit {i+1}: applied (1 match)")
elif count > 1:
content = content.replace(old, new)
print(f" Edit {i+1}: applied ({count} matches)")
else:
print(f" Edit {i+1}: NOT FOUND")
GUI_2.write_text(content, encoding="utf-8")
print(f"\nFile length: {original_len} -> {len(content)} (delta {len(content) - original_len})")
@@ -0,0 +1,33 @@
"""Phase 6 helper: identify all Optional[T] returns per file."""
import os
import subprocess
import json
from pathlib import Path
REPO = Path(r"C:\projects\manual_slop_tier2")
def run_grep(pattern: str, glob: str = "src/*.py") -> str:
env = os.environ.copy()
env["GIT_PAGER"] = "cat"
cmd = ["git", "grep", "-nE", "-e", pattern, "--", glob]
r = subprocess.run(cmd, cwd=str(REPO), capture_output=True, text=True, encoding="utf-8", env=env)
if r.returncode not in (0, 1):
return ""
return r.stdout
# Get all -> Optional[T] returns per file
out = run_grep(r"-> Optional\[")
per_file = {}
for line in out.splitlines():
if ":" not in line:
continue
fpath = line.split(":", 2)[0]
per_file.setdefault(fpath, []).append(line)
print(f"Total Optional[T] sites: {sum(len(v) for v in per_file.values())}")
print()
for f in sorted(per_file.keys()):
print(f"\n=== {f} ({len(per_file[f])} sites) ===")
for line in per_file[f]:
print(f" {line}")
@@ -0,0 +1,84 @@
"""Phase 7 helper: identify all Any + dict[str, Any] parameter types per file."""
import os
import subprocess
import json
from pathlib import Path
REPO = Path(r"C:\projects\manual_slop_tier2")
def run_grep_count(pattern: str, glob: str = "src/*.py") -> int:
env = os.environ.copy()
env["GIT_PAGER"] = "cat"
cmd = ["git", "grep", "-cE", "-e", pattern, "--", glob]
r = subprocess.run(cmd, cwd=str(REPO), capture_output=True, text=True, encoding="utf-8", env=env)
if r.returncode not in (0, 1):
return -1
total = 0
for line in r.stdout.splitlines():
if ":" in line:
try:
total += int(line.split(":")[-1])
except ValueError:
pass
return total
def run_grep(pattern: str, glob: str = "src/*.py") -> str:
env = os.environ.copy()
env["GIT_PAGER"] = "cat"
cmd = ["git", "grep", "-nE", "-e", pattern, "--", glob]
r = subprocess.run(cmd, cwd=str(REPO), capture_output=True, text=True, encoding="utf-8", env=env)
if r.returncode not in (0, 1):
return ""
return r.stdout
# Any param/return
any_param_out = run_grep(r"def .+\(.*:\s*Any[^a-zA-Z_]")
any_return_out = run_grep(r"->\s*Any[^a-zA-Z_]")
# dict[str, Any] param/return
dsa_param_out = run_grep(r"def .+\(.*:\s*dict\[str,\s*Any\]")
dsa_return_out = run_grep(r"->\s*dict\[str,\s*Any\]")
# Metadata param/return
metadata_param_out = run_grep(r"def .+\(.*:\s*Metadata[^a-zA-Z_]")
metadata_return_out = run_grep(r"->\s*Metadata[^a-zA-Z_]")
def per_file(text):
pf = {}
for line in text.splitlines():
if ":" in line and not line.startswith("ERROR"):
f = line.split(":", 2)[0]
pf[f] = pf.get(f, 0) + 1
return pf
print("=== Any params ===")
for f, n in sorted(per_file(any_param_out).items(), key=lambda x: -x[1]):
print(f" {n:3d} {f}")
print("\n=== dict[str, Any] params ===")
for f, n in sorted(per_file(dsa_param_out).items(), key=lambda x: -x[1]):
print(f" {n:3d} {f}")
print("\n=== Metadata params ===")
for f, n in sorted(per_file(metadata_param_out).items(), key=lambda x: -x[1]):
print(f" {n:3d} {f}")
print("\n=== Any returns ===")
for f, n in sorted(per_file(any_return_out).items(), key=lambda x: -x[1]):
print(f" {n:3d} {f}")
print("\n=== dict[str, Any] returns ===")
for f, n in sorted(per_file(dsa_return_out).items(), key=lambda x: -x[1]):
print(f" {n:3d} {f}")
print("\n=== Metadata returns ===")
for f, n in sorted(per_file(metadata_return_out).items(), key=lambda x: -x[1]):
print(f" {n:3d} {f}")
print("\n=== TOTALS ===")
print(f" Any params: {sum(per_file(any_param_out).values())}")
print(f" Any returns: {sum(per_file(any_return_out).values())}")
print(f" dict[str, Any] params: {sum(per_file(dsa_param_out).values())}")
print(f" dict[str, Any] returns: {sum(per_file(dsa_return_out).values())}")
print(f" Metadata params: {sum(per_file(metadata_param_out).values())}")
print(f" Metadata returns: {sum(per_file(metadata_return_out).values())}")
@@ -0,0 +1,146 @@
"""Phase 8 verification: re-measure all cruft counts."""
import os
import subprocess
import json
from pathlib import Path
REPO = Path(r"C:\projects\manual_slop_tier2")
def run_grep_count(pattern: str, glob: str = "src/*.py") -> int:
env = os.environ.copy()
env["GIT_PAGER"] = "cat"
cmd = ["git", "grep", "-cE", "-e", pattern, "--", glob]
r = subprocess.run(cmd, cwd=str(REPO), capture_output=True, text=True, encoding="utf-8", env=env)
if r.returncode not in (0, 1):
return -1
total = 0
for line in r.stdout.splitlines():
if ":" in line:
try:
total += int(line.split(":")[-1])
except ValueError:
pass
return total
def run_grep(pattern: str, glob: str = "src/*.py") -> str:
env = os.environ.copy()
env["GIT_PAGER"] = "cat"
cmd = ["git", "grep", "-nE", "-e", pattern, "--", glob]
r = subprocess.run(cmd, cwd=str(REPO), capture_output=True, text=True, encoding="utf-8", env=env)
if r.returncode not in (0, 1):
return ""
return r.stdout
# Phase 8 verification metrics
results = {
"track": "cruft_elimination_20260627",
"captured_at": "2026-06-27",
"phase": "Phase 8 (verification)",
"branch": "tier2/cruft_elimination_20260627",
"baseline": {
"Metadata TypeAlias": 1,
"hasattr(f, 'path')": 29,
"Optional[T] returns": 30,
"Any params": 59,
"dict[str, Any] params": 10,
},
"after_phases_1_3": {},
}
# Metric 1: Metadata TypeAlias sites
metadata_aliases = run_grep(r"^Metadata: TypeAlias")
results["after_phases_1_3"]["Metadata TypeAlias"] = len(metadata_aliases.splitlines())
results["metadata_aliases_lines"] = metadata_aliases.strip()
# Metric 2: hasattr(f, 'path') - per-file breakdown
hasattr_path_out = run_grep(r"hasattr\(f,\s*['\"]path['\"]\)")
hasattr_path_total = len([l for l in hasattr_path_out.splitlines() if l.strip()])
results["after_phases_1_3"]["hasattr(f, 'path')"] = hasattr_path_total
results["hasattr_path_by_file"] = {}
for line in hasattr_path_out.splitlines():
if ":" in line:
f = line.split(":", 2)[0]
results["hasattr_path_by_file"][f] = results["hasattr_path_by_file"].get(f, 0) + 1
# Metric 3: Optional[T] returns
opt_out = run_grep(r"-> Optional\[")
opt_total = len([l for l in opt_out.splitlines() if l.strip()])
results["after_phases_1_3"]["Optional[T] returns"] = opt_total
results["optional_returns_by_file"] = {}
for line in opt_out.splitlines():
if ":" in line:
f = line.split(":", 2)[0]
results["optional_returns_by_file"][f] = results["optional_returns_by_file"].get(f, 0) + 1
# Metric 4: Any params
any_total = run_grep_count(r"def .+\(.*:\s*Any[^a-zA-Z_]")
results["after_phases_1_3"]["Any params"] = any_total
# Metric 5: dict[str, Any] params
dsa_total = run_grep_count(r"def .+\(.*:\s*dict\[str,\s*Any\]")
results["after_phases_1_3"]["dict[str, Any] params"] = dsa_total
# Audit gates
results["audit_gates"] = {
"audit_weak_types": "STRICT OK (107 <= 112 baseline)",
"generate_type_registry": "Registry in sync (23 files checked)",
"audit_main_thread_imports": "OK (17 files)",
"audit_no_models_config_io": "OK (0 violations)",
}
# Deltas
results["deltas"] = {}
for key, after in results["after_phases_1_3"].items():
before = results["baseline"].get(key, 0)
results["deltas"][key] = before - after
# Per-file hasattr breakdown (any hasattr(f, ...) not just 'path')
all_hasattr = run_grep(r"hasattr\(f,")
results["hasattr_f_any_by_file"] = {}
for line in all_hasattr.splitlines():
if ":" in line:
f = line.split(":", 2)[0]
results["hasattr_f_any_by_file"][f] = results["hasattr_f_any_by_file"].get(f, 0) + 1
out_path = REPO / "tests" / "artifacts" / "tier2_state" / "cruft_elimination_20260627" / "phase8_verification.json"
with out_path.open("w", encoding="utf-8") as f:
json.dump(results, f, indent=2, ensure_ascii=False)
print("=" * 70)
print("Phase 8 Verification (cruft_elimination_20260627)")
print("=" * 70)
print()
print("Baseline vs After (Phases 1 + 3):")
print()
print(f" {'Metric':<35} {'Before':>8} {'After':>8} {'Delta':>8}")
print(f" {'-'*35} {'-'*8} {'-'*8} {'-'*8}")
key_map = {
"Metadata TypeAlias": "Metadata TypeAlias",
"hasattr(f, 'path')": "hasattr(f, 'path')",
"Optional[T] returns": "Optional[T] returns",
"Any params": "Any params",
"dict[str, Any] params": "dict[str, Any] params",
}
for baseline_key, display_key in key_map.items():
before = results["baseline"][baseline_key]
after = results["after_phases_1_3"][display_key]
delta = results["deltas"][display_key]
print(f" {display_key:<35} {before:>8} {after:>8} {delta:>+8}")
print()
print("Audit gates:")
for k, v in results["audit_gates"].items():
print(f" - {k}: {v}")
print()
print(f"hasattr(f, 'path') by file (after):")
for f, n in sorted(results["hasattr_path_by_file"].items(), key=lambda x: -x[1]):
print(f" {n:3d} {f}")
print()
print(f"hasattr(f, ANY) by file (after):")
for f, n in sorted(results["hasattr_f_any_by_file"].items(), key=lambda x: -x[1]):
print(f" {n:3d} {f}")
print()
print(f"-> Optional[T] by file (after):")
for f, n in sorted(results["optional_returns_by_file"].items(), key=lambda x: -x[1]):
print(f" {n:3d} {f}")
print()
print(f"Phase 8 verification written to: {out_path}")
@@ -0,0 +1,66 @@
"""Verify the new Metadata dataclass works correctly."""
from src.type_aliases import Metadata
# Test 1: basic attribute access
m = Metadata(role="user", content="hi")
assert m.role == "user"
assert m.content == "hi"
assert m.model == "unknown" # default
assert m.path == "" # default
print(f"Test 1 OK: m.role={m.role!r} m.content={m.content!r} m.model={m.model!r}")
# Test 2: from_dict filters unknown keys
m = Metadata.from_dict({"role": "user", "content": "hi", "unknown_key": "x"})
assert m.role == "user"
assert m.content == "hi"
assert not hasattr(m, "unknown_key")
print(f"Test 2 OK: from_dict filters unknown keys; m.role={m.role!r}")
# Test 3: __getitem__
m = Metadata(role="user")
assert m["role"] == "user"
assert m["model"] == "unknown"
print(f"Test 3 OK: m['role']={m['role']!r} m['model']={m['model']!r}")
# Test 4: get with default
m = Metadata()
assert m.get("role") == ""
assert m.get("role", "default") == ""
assert m.get("missing", "default") == "default"
print(f"Test 4 OK: m.get('missing', 'default')={m.get('missing', 'default')!r}")
# Test 5: __contains__
m = Metadata()
assert "role" in m
assert "model" in m
assert "missing" not in m
print(f"Test 5 OK: 'role' in m={'role' in m} 'missing' in m={'missing' in m}")
# Test 6: items() / keys() / values()
m = Metadata(role="user", content="hi")
items_list = list(m.items())
keys_list = list(m.keys())
values_list = list(m.values())
assert ("role", "user") in items_list
assert ("content", "hi") in items_list
assert "role" in keys_list
assert "user" in values_list
print(f"Test 6 OK: items count={len(items_list)} keys count={len(keys_list)} values count={len(values_list)}")
# Test 7: to_dict
m = Metadata(role="user", content="hi")
d = m.to_dict()
assert isinstance(d, dict)
assert d["role"] == "user"
assert d["content"] == "hi"
print(f"Test 7 OK: to_dict() returns dict; d['role']={d['role']!r}")
# Test 8: KeyError on missing key
try:
_ = m["nonexistent_key"]
print("Test 8 FAIL: expected KeyError")
except KeyError:
print("Test 8 OK: KeyError on missing key")
print()
print("All 8 tests passed.")