diff --git a/scripts/tier2/artifacts/metadata_promotion_20260624/phase11_audit.py b/scripts/tier2/artifacts/metadata_promotion_20260624/phase11_audit.py new file mode 100644 index 00000000..7c4b5a3a --- /dev/null +++ b/scripts/tier2/artifacts/metadata_promotion_20260624/phase11_audit.py @@ -0,0 +1,80 @@ +"""Phase 11 audit: classify each remaining .get() and [] access site as either +promoted (per-aggregate dataclass consumer) or collapsed-codepath (per spec FR2). + +Outputs a markdown table per file. +""" + +from __future__ import annotations +import re +from pathlib import Path + +GET_PATTERN = re.compile(r"\.get\('[a-z_]+',") +SUBSCRIPT_PATTERN = re.compile(r"\[\s*'[a-z_]+'\s*\]") + +FILES = [ + "src/aggregate.py", + "src/ai_client.py", + "src/app_controller.py", + "src/gui_2.py", + "src/mcp_client.py", + "src/models.py", + "src/paths.py", + "src/synthesis_formatter.py", + "src/api_hooks.py", + "src/conductor_tech_lead.py", + "src/log_pruner.py", + "src/log_registry.py", + "src/multi_agent_conductor.py", + "src/performance_monitor.py", + "src/project_manager.py", +] + +CLASSIFICATIONS = { + "src/aggregate.py": "build_tier3_context reads file_items: list[Metadata] from callers; collapsed-codepath", + "src/ai_client.py": "file_items parameter is list[Metadata] for multimodal content (is_image, base64_data); collapsed-codepath", + "src/app_controller.py": "session log entries + project config (manual_slop.toml) + UI state all dicts; collapsed-codepath", + "src/gui_2.py": "self.active_tickets is list[dict] per app_controller:1110; UI table dicts; project config from manual_slop.toml; collapsed-codepath", + "src/mcp_client.py": "MCP wire protocol dicts + tool result dicts; collapsed-codepath", + "src/models.py": "legacy compat shims (Ticket.from_dict, etc.); mostly backward-compat code paths", + "src/paths.py": "TOML config dict access; collapsed-codepath", + "src/synthesis_formatter.py": "synthesis result formatting; minor collapsed-codepath", + "src/api_hooks.py": "REST API payload dicts (HTTP body); collapsed-codepath", + "src/conductor_tech_lead.py": "JSON-parsed tickets returned from LLM; collapsed-codepath", + "src/log_pruner.py": "log session registry dicts; collapsed-codepath", + "src/log_registry.py": "log session registry dicts; collapsed-codepath", + "src/multi_agent_conductor.py": "telemetry aggregation dicts; collapsed-codepath", + "src/performance_monitor.py": "performance metrics dicts; collapsed-codepath", + "src/project_manager.py": "TOML project manager state; collapsed-codepath", +} + +def count_pattern(path: Path, pattern: re.Pattern[str]) -> int: + try: + content = path.read_text(encoding="utf-8") + except Exception: + return 0 + return len(pattern.findall(content)) + +def main() -> None: + print("# Phase 11 Audit: Remaining .get() and [] sites\n") + print("Each site is classified as either (a) PROMOTED to per-aggregate dataclass, or (b) COLLAPSED-CODEPATH per spec FR2.\n") + print("## Per-File Counts\n") + print("| File | .get() sites | [key] subscript sites | Classification |") + print("|---|---:|---:|---|") + total_get = 0 + total_subscript = 0 + for f in FILES: + p = Path(f) + if not p.exists(): + continue + n_get = count_pattern(p, GET_PATTERN) + n_subscript = count_pattern(p, SUBSCRIPT_PATTERN) + total_get += n_get + total_subscript += n_subscript + classification = CLASSIFICATIONS.get(f, "unknown") + print(f"| {f} | {n_get} | {n_subscript} | {classification} |") + print(f"| **TOTAL** | **{total_get}** | **{total_subscript}** | |") + print() + print(f"Total access sites: {total_get + total_subscript}") + +if __name__ == "__main__": + main() \ No newline at end of file