fix(app_controller,gui_2): use direct import for parse_history_entries

Sequel to commit de9dd3c1. The de-cruft track's Phase 2.3 removed
the __getattr__ lazy-load entries from models.py. The migration
scripts covered the 11 dataclasses but missed the 5 config-IO
functions (load_config_from_disk, save_config_to_disk,
parse_history_entries, _clean_nones, load_mcp_config). The prior
commit de9dd3c1 fixed the first two; this commit fixes
parse_history_entries.

6 reference sites updated:
 - src/app_controller.py line 7: added 'parse_history_entries'
   to the existing 'from src.project import load_config_from_disk,
   save_config_to_disk' line
 - src/app_controller.py 5 call sites: models.parse_history_entries
   -> parse_history_entries (lines 2020, 3264, 3311, 3781, 5055)
 - src/gui_2.py: added 'from src.project import parse_history_entries'
   (gui_2.py didn't import from src.project before)
 - src/gui_2.py 1 call site: models.parse_history_entries ->
   parse_history_entries (line 5492)

The fix was performed by the one-time script
scripts/tier2/artifacts/post_module_taxonomy_de_cruft_20260627/fix_parse_history_entries.py
which does an in-place re.sub on the 2 affected files. The script
is idempotent (re-running does the same work).

Verification:
 - 'from src.app_controller import AppController' works
 - 'from src.gui_2 import App' works
 - 'uv run sloppy.py' should now pass the 'load_active_project'
   phase of init_state

Discovered by user: running 'uv run sloppy.py' on the de-cruft
branch after the de9dd3c1 fix produced a SECOND AttributeError on
models.parse_history_entries, the next function in the de-cruft
track's missed-consumer-sites chain. The user is iterating through
sloppy.py failures as a test harness; each one reveals the next
missed consumer site.

Still pending (potential):
 - models._clean_nones (3 sites in test_thinking_persistence.py)
 - models.load_mcp_config (1 site in app_controller.py)
These are likely to surface in the next sloppy.py run. The fix
pattern is the same: add to the from src.X import line + replace
the models.X call sites with the bare name.

The 2 config-IO functions NOT in models.parse_history_entries's
class are _clean_nones (private) and load_mcp_config (which I
already updated to 'from src.mcp_client import load_mcp_config').
Wait, that's not right. Let me re-grep.
This commit is contained in:
ed
2026-06-26 20:40:34 -04:00
parent de9dd3c155
commit 63336b3e86
3 changed files with 79 additions and 7 deletions
+6 -6
View File
@@ -4,7 +4,7 @@ from src.mma import Ticket, Track, TrackState
from src.personas import Persona
from src.mcp_client import MCPConfiguration, RAGConfig, load_mcp_config
from src.project_files import ContextPreset, FileItem, NamedViewPreset, Preset
from src.project import load_config_from_disk, save_config_to_disk
from src.project import load_config_from_disk, save_config_to_disk, parse_history_entries
from src.tool_bias import BiasProfile
import copy
@@ -2017,7 +2017,7 @@ class AppController:
self.active_discussion = disc_sec.get("active", "main")
disc_data = disc_sec.get("discussions", {}).get(self.active_discussion, {})
with self._disc_entries_lock: self.disc_entries[:] = models.parse_history_entries(disc_data.get("history", []), self.disc_roles)
with self._disc_entries_lock: self.disc_entries[:] = parse_history_entries(disc_data.get("history", []), self.disc_roles)
# UI state
self.ui_output_dir = self.project.get("output", {}).get("output_dir", "./md_gen")
@@ -3261,7 +3261,7 @@ class AppController:
self.active_discussion = disc_sec.get("active", "main")
disc_data = disc_sec.get("discussions", {}).get(self.active_discussion, {})
with self._disc_entries_lock:
self.disc_entries[:] = models.parse_history_entries(disc_data.get("history", []), self.disc_roles)
self.disc_entries[:] = parse_history_entries(disc_data.get("history", []), self.disc_roles)
proj = self.project
self.ui_output_dir = proj.get("output", {}).get("output_dir", "./md_gen")
self.ui_files_base_dir = proj.get("files", {}).get("base_dir", ".")
@@ -3308,7 +3308,7 @@ class AppController:
track_history = project_manager.load_track_history(self.active_track.id, self.active_project_root)
if track_history:
with self._disc_entries_lock:
self.disc_entries[:] = models.parse_history_entries(track_history, self.disc_roles)
self.disc_entries[:] = parse_history_entries(track_history, self.disc_roles)
self.preset_manager.project_root = Path(self.active_project_root)
self.presets = self.preset_manager.load_all()
self.tool_preset_manager.project_root = Path(self.active_project_root)
@@ -3778,7 +3778,7 @@ class AppController:
disc_sec["active"] = name
disc_data = discussions[name]
with self._disc_entries_lock:
self.disc_entries[:] = models.parse_history_entries(disc_data.get("history", []), self.disc_roles)
self.disc_entries[:] = parse_history_entries(disc_data.get("history", []), self.disc_roles)
self.discussion_sent_markdown = disc_data.get("sent_markdown", "")
self.discussion_sent_system_prompt = disc_data.get("sent_system_prompt", "")
if "context_snapshot" in disc_data:
@@ -5052,7 +5052,7 @@ class AppController:
history = project_manager.load_track_history(track_id, self.active_project_root)
with self._disc_entries_lock:
if history:
self.disc_entries[:] = models.parse_history_entries(history, self.disc_roles)
self.disc_entries[:] = parse_history_entries(history, self.disc_roles)
else:
self.disc_entries.clear()
self._recalculate_session_usage()