# #region MigrateHierarchical [C:4] [TYPE Module] [SEMANTICS migration,hierarchical,ids] # @defgroup Migration Script to upgrade flat contract IDs to hierarchical Domain.Name format. # @BRIEF Dry-run first, then batch-apply hierarchical ID migration for all contracts in the project. # @RATIONALE 97.9% of contracts have flat IDs (e.g. UserListModel) that die at HCA 128×. # Hierarchical IDs (Users.ListModel) survive as statistical signatures. # Script infers domain prefix from parent contract → @SEMANTICS → file path → fallback. # @SIDE_EFFECT Modifies #region/#endregion anchors and @RELATION edges across all source files. # Creates axiom checkpoints before each batch. # @INVARIANT Anchor pairs remain matched. @RELATION edges updated. NO business logic changed. import re import sys from collections import defaultdict from pathlib import Path # ── Domain prefix inference ────────────────────────────────────── # Path-based inference (ordered: most specific first) PATH_TO_DOMAIN = [ ("frontend/src/lib/models/", "Models"), ("frontend/src/lib/components/ui/", "UI"), ("frontend/src/lib/components/translate/", "Translate"), ("frontend/src/lib/components/dashboard/", "Dashboard"), ("frontend/src/lib/components/llm/", "LLM"), ("frontend/src/lib/components/dataset-review/", "DatasetReview"), ("frontend/src/lib/components/settings/", "Settings"), ("frontend/src/lib/components/layout/", "Layout"), ("frontend/src/lib/components/assistant/","Assistant"), ("frontend/src/lib/components/tasks/", "Tasks"), ("frontend/src/lib/components/", "Components"), ("frontend/src/lib/ui/", "UI"), ("frontend/src/lib/stores/", "Stores"), ("frontend/src/lib/api/", "Api"), ("frontend/src/routes/", "Routes"), ("frontend/src/types/", "Types"), ("backend/src/api/routes/assistant/", "AssistantApi"), ("backend/src/api/routes/", "Api"), ("backend/src/core/task_manager/", "TaskManager"), ("backend/src/core/auth/", "Auth"), ("backend/src/core/migration/", "Migration"), ("backend/src/core/plugins/", "Plugin"), ("backend/src/core/", "Core"), ("backend/src/services/dataset_review/", "DatasetReview"), ("backend/src/services/", "Services"), ("backend/src/models/", "Models"), ("backend/src/schemas/", "Schemas"), ("backend/src/plugins/translate/", "Translate"), ("backend/src/plugins/llm_analysis/", "LLMAnalysis"), ("backend/src/plugins/git/", "Git"), ("backend/src/plugins/storage/", "Storage"), ("backend/src/plugins/", "Plugin"), ("backend/tests/", "Tests"), ] # @SEMANTICS keyword → domain prefix SEMANTICS_TO_DOMAIN = { "auth": "Auth", "login": "Auth", "token": "Auth", "migration": "Migration", "dashboard": "Dashboard", "dataset": "Dataset", "translation": "Translate", "translate": "Translate", "llm": "LLM", "git": "Git", "storage": "Storage", "plugin": "Plugin", "task": "Tasks", "test": "Tests", "api": "Api", "ui": "UI", "users": "Users", "roles": "Roles", "settings": "Settings", "profile": "Profile", "reports": "Reports", "validation": "Validation", "backup": "Backup", "mapper": "Mapper", "debug": "Debug", "assistant": "Assistant", "admin": "Admin", "notification": "Notifications", "schedule": "Schedule", "logging": "Logging", "indexing": "Index", "curation": "Curator", "semantic": "Semantic", "screenshot": "Screenshot", "health": "Health", } # ── File discovery ─────────────────────────────────────────────── def find_source_files(root: Path) -> list[Path]: """Find all source files with contracts.""" patterns = ["**/*.py", "**/*.svelte", "**/*.svelte.ts"] source_dirs = [ root / "backend/src", root / "frontend/src", root / "backend/tests", ] files = [] for d in source_dirs: if not d.exists(): continue for pat in patterns: files.extend(d.rglob(pat.split("/")[-1])) return sorted(set(files)) # ── Contract parsing ───────────────────────────────────────────── ANCHOR_RE = re.compile( r'^(?P\s*(?:#|//|