import re from pathlib import Path ROOT = Path(__file__).resolve().parents[1] INVENTORY = ROOT / "docs/memory/code_modularization_inventory_20260430.md" GUIDE = ROOT / "docs/guides/modularization_governance.md" def _python_line_counts(): ignored_parts = {".git", ".venv", "venv", "backups", "tests", "__pycache__", ".pytest_cache"} ignored_prefixes = { ("docs", "design"), ("docs", "design_audit_frontend"), } for path in ROOT.rglob("*.py"): parts = path.relative_to(ROOT).parts if any(part in ignored_parts for part in parts): continue if parts[:2] in ignored_prefixes: continue if len(parts) >= 2 and parts[0] == ".claude" and parts[1] == "worktrees": continue with path.open(encoding="utf-8", errors="ignore") as handle: yield path.relative_to(ROOT).as_posix(), sum(1 for _ in handle) def test_large_python_modules_are_tracked_in_modularization_inventory(): inventory = INVENTORY.read_text(encoding="utf-8") large_modules = { path: lines for path, lines in _python_line_counts() if lines >= 800 } assert large_modules, "盤點應至少包含目前既有大檔" missing = [ f"{path} ({lines} lines)" for path, lines in sorted(large_modules.items()) if f"`{path}`" not in inventory ] assert missing == [] def test_modularization_inventory_line_counts_are_current_enough(): inventory = INVENTORY.read_text(encoding="utf-8") inventory_counts = { match.group("path"): int(match.group("lines")) for match in re.finditer( r"^\|\s*(?P\d+)\s*\|\s*`(?P[^`]+)`\s*\|", inventory, re.MULTILINE, ) } large_modules = { path: lines for path, lines in _python_line_counts() if lines >= 800 } stale = [] for path, current_lines in sorted(large_modules.items()): recorded_lines = inventory_counts.get(path) if recorded_lines is None: continue allowed_drift = max(50, int(current_lines * 0.1)) if abs(recorded_lines - current_lines) > allowed_drift: stale.append(f"{path}: recorded={recorded_lines}, current={current_lines}") assert stale == [] def test_modularization_governance_is_indexed_for_codex_sessions(): agents = (ROOT / "AGENTS.md").read_text(encoding="utf-8") constitution = (ROOT / "CONSTITUTION.md").read_text(encoding="utf-8") memory_index = (ROOT / "docs/memory/README.md").read_text(encoding="utf-8") assert "docs/guides/modularization_governance.md" in agents assert "docs/guides/modularization_governance.md" in constitution assert "code_modularization_inventory_20260430.md" in agents assert "code_modularization_inventory_20260430.md" in memory_index assert GUIDE.exists()