# [DEF:generate_semantic_map:Module] # @PURPOSE: Scans the codebase to generate a Semantic Map, Module Map, and Compliance Report based on the System Standard. # @PRE: Valid directory containing code to scan. # @POST: Files map.json, .ai/PROJECT_MAP.md, .ai/MODULE_MAP.md, and compliance reports generated. # @TIER: STANDARD # @SEMANTICS: semantic_analysis, parser, map_generator, compliance_checker, tier_validation, svelte_props, data_flow, module_map # @LAYER: DevOps/Tooling # @INVARIANT: All DEF anchors must have matching closing anchors; TIER determines validation strictness. # @RELATION: READS -> FileSystem # @RELATION: PRODUCES -> semantics/semantic_map.json # @RELATION: PRODUCES -> .ai/PROJECT_MAP.md # @RELATION: PRODUCES -> .ai/MODULE_MAP.md # @RELATION: PRODUCES -> semantics/reports/semantic_report_*.md # [SECTION: IMPORTS] import os import re import json import datetime import fnmatch import argparse from enum import Enum from dataclasses import dataclass, field from typing import Dict, List, Optional, Any, Pattern, Tuple, Set # Mock belief_scope for the script itself to avoid import issues class belief_scope: # [DEF:__init__:Function] # @TIER: TRIVIAL # @PURPOSE: Mock init for self-containment. # @PRE: name is a string. # @POST: Instance initialized. def __init__(self, name): self.name = name # [/DEF:__init__:Function] # [DEF:__enter__:Function] # @TIER: TRIVIAL # @PURPOSE: Mock enter. # @PRE: Instance initialized. # @POST: Returns self. def __enter__(self): return self # [/DEF:__enter__:Function] # [DEF:__exit__:Function] # @TIER: TRIVIAL # @PURPOSE: Mock exit. # @PRE: Context entered. # @POST: Context exited. def __exit__(self, *args): pass # [/DEF:__exit__:Function] # [/SECTION] # [SECTION: CONFIGURATION] class Tier(Enum): # [DEF:Tier:Class] # @TIER: TRIVIAL # @PURPOSE: Enumeration of semantic tiers defining validation strictness. CRITICAL = "CRITICAL" STANDARD = "STANDARD" TRIVIAL = "TRIVIAL" # [/DEF:Tier:Class] class Severity(Enum): # [DEF:Severity:Class] # @TIER: TRIVIAL # @PURPOSE: Severity levels for compliance issues. ERROR = "ERROR" WARNING = "WARNING" INFO = "INFO" # [/DEF:Severity:Class] PROJECT_ROOT = "." IGNORE_DIRS = { ".git", "__pycache__", "node_modules", "venv", ".pytest_cache", ".kilocode", "backups", "logs", "semantics", "specs", ".venv" } IGNORE_FILES = { "package-lock.json", "poetry.lock", "yarn.lock" } IGNORE_PATH_PREFIXES = { ".ai/shots/" } IGNORE_EXACT_PATHS = { ".ai/shots" } OUTPUT_JSON = "semantics/semantic_map.json" OUTPUT_COMPRESSED_MD = ".ai/PROJECT_MAP.md" OUTPUT_MODULE_MAP_MD = ".ai/MODULE_MAP.md" REPORTS_DIR = "semantics/reports" # Tier-based mandatory tags aligned with .ai/standards/semantics.md TIER_MANDATORY_TAGS = { Tier.CRITICAL: { "Module": ["PURPOSE", "LAYER", "SEMANTICS", "TIER", "INVARIANT", "RELATION"], "Component": ["PURPOSE", "LAYER", "SEMANTICS", "TIER", "INVARIANT", "RELATION", "UX_STATE", "UX_FEEDBACK", "UX_RECOVERY", "UX_REACTIVITY"], "Function": ["PURPOSE", "PRE", "POST", "SIDE_EFFECT", "DATA_CONTRACT", "TEST_CONTRACT", "TEST_SCENARIO", "TEST_FIXTURE", "TEST_EDGE", "TEST_INVARIANT"], "Class": ["PURPOSE", "TIER", "INVARIANT"], "Store": ["PURPOSE", "TIER", "INVARIANT"], "Block": ["PURPOSE", "TIER"] }, Tier.STANDARD: { "Module": ["PURPOSE", "LAYER", "SEMANTICS", "TIER", "RELATION"], "Component": ["PURPOSE", "LAYER", "SEMANTICS", "TIER", "RELATION", "UX_STATE", "UX_REACTIVITY"], "Function": ["PURPOSE", "PRE", "POST", "SIDE_EFFECT", "DATA_CONTRACT"], "Class": ["PURPOSE", "TIER"], "Store": ["PURPOSE", "TIER"], "Block": ["PURPOSE"] }, Tier.TRIVIAL: { "Module": ["PURPOSE"], "Component": ["PURPOSE"], "Function": ["PURPOSE"], "Class": ["PURPOSE"], "Store": ["PURPOSE"], "Block": ["PURPOSE"] } } ALLOWED_RELATION_PREDICATES = { "DEPENDS_ON", "CALLS", "INHERITS", "IMPLEMENTS", "DISPATCHES", "BINDS_TO" } # Tier-based belief state requirements TIER_BELIEF_REQUIRED = { Tier.CRITICAL: True, Tier.STANDARD: True, Tier.TRIVIAL: False } # [/SECTION] # [DEF:ComplianceIssue:Class] # @TIER: TRIVIAL # @PURPOSE: Represents a single compliance issue with severity. @dataclass class ComplianceIssue: message: str severity: Severity line_number: Optional[int] = None def to_dict(self) -> Dict[str, Any]: return { "message": self.message, "severity": self.severity.value, "line_number": self.line_number } # [/DEF:ComplianceIssue:Class] # [DEF:SemanticEntity:Class] # @TIER: CRITICAL # @PURPOSE: Represents a code entity (Module, Function, Component) found during parsing. # @INVARIANT: start_line is always set; end_line is set upon closure; tier defaults to STANDARD. class SemanticEntity: # [DEF:__init__:Function] # @TIER: STANDARD # @PURPOSE: Initializes a new SemanticEntity instance. # @PRE: name, type_, start_line, file_path are provided. # @POST: Instance is initialized with default values. def __init__(self, name: str, type_: str, start_line: int, file_path: str): with belief_scope("__init__"): self.name = name self.type = type_ self.start_line = start_line self.end_line: Optional[int] = None self.file_path = file_path self.tags: Dict[str, str] = {} self.relations: List[Dict[str, str]] = [] self.children: List['SemanticEntity'] = [] self.parent: Optional['SemanticEntity'] = None self.compliance_issues: List[ComplianceIssue] = [] self.has_belief_scope: bool = False self.has_console_log: bool = False # New fields for enhanced Svelte analysis self.props: List[Dict[str, Any]] = [] self.events: List[str] = [] self.data_flow: List[Dict[str, str]] = [] self.has_export_let: bool = False self.has_reactive_label: bool = False self.has_runes: bool = False # [/DEF:__init__:Function] # [DEF:get_tier:Function] # @TIER: STANDARD # @PURPOSE: Returns the tier of the entity, defaulting to STANDARD. # @PRE: tags dictionary is accessible. # @POST: Returns Tier enum value. def get_tier(self) -> Tier: with belief_scope("get_tier"): tier_str = self.tags.get("TIER", "STANDARD").upper() try: base_tier = Tier(tier_str) except ValueError: base_tier = Tier.STANDARD file_path_lower = self.file_path.lower() is_test_entity = ( "test" in file_path_lower or "/__tests__/" in self.file_path or self.name.startswith("test_") ) # 1. Tests should never be higher than STANDARD if is_test_entity and base_tier == Tier.CRITICAL: return Tier.STANDARD # 2. Non-route Svelte entities should not be escalated beyond STANDARD by path heuristics. if self.file_path.endswith(".svelte"): is_route_level_svelte = any( marker in self.name for marker in ["+page", "+layout", "Page", "Layout"] ) if not is_route_level_svelte and base_tier == Tier.CRITICAL: return Tier.STANDARD # 3. Tooling scripts should not be escalated beyond STANDARD. if ("scripts/" in self.file_path or "_tui.py" in self.file_path) and base_tier == Tier.CRITICAL: return Tier.STANDARD # 4. Promote only module-like entities in critical domains by path heuristic. # This prevents path segments like "migration" from forcing every nested # Block/Function/Component in a route file into CRITICAL validation. critical_keywords = ["auth", "security", "jwt", "database", "migration", "config", "session"] module_like_types = {"Module", "Class", "Store"} if ( self.type in module_like_types and any(keyword in file_path_lower for keyword in critical_keywords) and not is_test_entity and base_tier != Tier.TRIVIAL ): return Tier.CRITICAL return base_tier # [/DEF:get_tier:Function] # [DEF:to_dict:Function] # @TIER: STANDARD # @PURPOSE: Serializes the entity to a dictionary for JSON output. # @PRE: Entity is fully populated. # @POST: Returns a dictionary representation. def to_dict(self) -> Dict[str, Any]: with belief_scope("to_dict"): result = { "name": self.name, "type": self.type, "tier": self.get_tier().value, "start_line": self.start_line, "end_line": self.end_line, "tags": self.tags, "relations": self.relations, "children": [c.to_dict() for c in self.children], "compliance": { "valid": len([i for i in self.compliance_issues if i.severity == Severity.ERROR]) == 0, "issues": [i.to_dict() for i in self.compliance_issues], "score": self.get_score() } } if self.props: result["props"] = self.props if self.events: result["events"] = self.events if self.data_flow: result["data_flow"] = self.data_flow return result # [/DEF:to_dict:Function] # [DEF:validate:Function] # @TIER: CRITICAL # @PURPOSE: Checks for semantic compliance based on TIER requirements. # @PRE: Entity structure is complete; tier is determined. # @POST: Populates self.compliance_issues with severity levels. # @SIDE_EFFECT: Modifies self.compliance_issues list. def validate(self): with belief_scope("validate"): tier = self.get_tier() # 1. Check Closure (required for ALL tiers) if self.end_line is None: self.compliance_issues.append(ComplianceIssue( f"Unclosed Anchor: [DEF:{self.name}:{self.type}] started at line {self.start_line}", Severity.ERROR, self.start_line )) # 2. Check Mandatory Tags based on TIER required = TIER_MANDATORY_TAGS.get(tier, {}).get(self.type, []) for req_tag in required: found = False if req_tag == "RELATION" and len(self.relations) > 0: found = True else: for existing_tag in self.tags: if existing_tag.upper() == req_tag: found = True break if not found: severity = Severity.ERROR if tier == Tier.CRITICAL else Severity.WARNING self.compliance_issues.append(ComplianceIssue( f"Missing Mandatory Tag: @{req_tag} (required for {tier.value} tier)", severity, self.start_line )) # 3. Validate relation predicates against GRACE-Poly allowlist for rel in self.relations: rel_type = rel.get("type", "").upper() if rel_type and rel_type not in ALLOWED_RELATION_PREDICATES: self.compliance_issues.append(ComplianceIssue( f"Invalid @RELATION predicate: {rel_type}. Allowed: {', '.join(sorted(ALLOWED_RELATION_PREDICATES))}", Severity.ERROR if tier == Tier.CRITICAL else Severity.WARNING, self.start_line )) # 4. Check for Belief State Logging based on TIER if self.type == "Function": belief_required = TIER_BELIEF_REQUIRED.get(tier, False) if belief_required: is_python = self.file_path.endswith(".py") has_belief = self.has_belief_scope if is_python else self.has_console_log if not has_belief: # Check if it's a special case (logger.py or mock functions) if "logger.py" not in self.file_path and "__" not in self.name: severity = Severity.ERROR if tier == Tier.CRITICAL else Severity.WARNING log_type = "belief_scope / molecular methods" if is_python else "console.log with [ID][STATE]" self.compliance_issues.append(ComplianceIssue( f"Missing Belief State Logging: Function should use {log_type} (required for {tier.value} tier)", severity, self.start_line )) # 5. Check for @INVARIANT in CRITICAL tier if tier == Tier.CRITICAL and self.type in ["Module", "Component", "Class"]: if "INVARIANT" not in [k.upper() for k in self.tags.keys()]: self.compliance_issues.append(ComplianceIssue( f"Missing @INVARIANT tag (required for CRITICAL tier)", Severity.ERROR, self.start_line )) # 6. Validate modern Svelte reactivity protocol if self.type == "Component" and self.file_path.endswith(".svelte"): strict_severity = Severity.ERROR if tier == Tier.CRITICAL else Severity.WARNING if self.has_export_let: self.compliance_issues.append(ComplianceIssue( "Svelte protocol violation: `export let` is forbidden; use `$props()`", strict_severity, self.start_line )) if self.has_reactive_label: self.compliance_issues.append(ComplianceIssue( "Svelte protocol violation: `$:` reactive label is forbidden; use runes `$state/$derived/$effect`", strict_severity, self.start_line )) # 7. Validate module length limit if self.type == "Module" and self.end_line is not None: module_length = self.end_line - self.start_line + 1 if module_length >= 300: self.compliance_issues.append(ComplianceIssue( f"Fractal limit warning: Module length is {module_length} lines (must be < 300)", Severity.WARNING, self.start_line )) # Recursive validation for child in self.children: child.validate() # [/DEF:validate:Function] # [DEF:get_score:Function] # @TIER: STANDARD # @PURPOSE: Calculates a compliance score (0.0 to 1.0) based on tier requirements. # @PRE: validate() has been called. # @POST: Returns a float score. def get_score(self) -> float: with belief_scope("get_score"): if self.end_line is None: return 0.0 tier = self.get_tier() score = 1.0 # Dynamic penalties based on Tier error_penalty = 0.5 if tier == Tier.CRITICAL else 0.3 warning_penalty = 0.15 # Count issues by severity errors = len([i for i in self.compliance_issues if i.severity == Severity.ERROR]) warnings = len([i for i in self.compliance_issues if i.severity == Severity.WARNING]) # Penalties score -= errors * error_penalty score -= warnings * warning_penalty # Check mandatory tags required = TIER_MANDATORY_TAGS.get(tier, {}).get(self.type, []) if required: found_count = 0 for req_tag in required: found = False if req_tag == "RELATION" and len(self.relations) > 0: found = True else: for existing_tag in self.tags: if existing_tag.upper() == req_tag: found_count += 1 found = True break if found_count < len(required): missing_ratio = 1 - (found_count / len(required)) score -= 0.3 * missing_ratio return max(0.0, score) # [/DEF:get_score:Function] # [/DEF:SemanticEntity:Class] # [DEF:get_patterns:Function] # @TIER: STANDARD # @PURPOSE: Returns regex patterns for a specific language. # @PRE: lang is either 'python' or 'svelte_js'. # @POST: Returns a dictionary of compiled regex patterns. # @PARAM: lang (str) - 'python' or 'svelte_js' def get_patterns(lang: str) -> Dict[str, Pattern]: with belief_scope("get_patterns"): if lang == "python": return { "anchor_start": re.compile(r"#\s*\[DEF:(?P[-\w\.]+):(?P\w+)\]"), "anchor_end": re.compile(r"#\s*\[/DEF:(?P[-\w\.]+):(?P\w+)\]"), "tag": re.compile(r"#\s*@(?P[A-Z_]+):\s*(?P.*)"), "relation": re.compile(r"#\s*@RELATION:\s*\[?(?P\w+)\]?\s*->\s*\[?(?P[^\]]+)\]?"), "func_def": re.compile(r"^\s*(async\s+)?def\s+(?P\w+)"), "belief_scope": re.compile(r"with\s+(\w+\.)?belief_scope\(|@believed\("), "molecular_log": re.compile(r"logger\.(explore|reason|reflect)\("), } else: return { "html_anchor_start": re.compile(r""), "html_anchor_end": re.compile(r""), "js_anchor_start": re.compile(r"//\s*\[DEF:(?P[-\w\.]+):(?P\w+)\]"), "js_anchor_end": re.compile(r"//\s*\[/DEF:(?P[-\w\.]+):(?P\w+)\]"), "html_tag": re.compile(r"@(?P[A-Z_]+):\s*(?P.*)"), "jsdoc_tag": re.compile(r"\*\s*@(?P[A-Za-z_]+)\s*:?\s*(?P.*)"), "relation": re.compile(r"(?:|{rel['type']}|{safe_other}\n") break f.write("```\n") print(f"Generated {OUTPUT_MODULE_MAP_MD}") # [/DEF:_generate_module_map:Function] # [/DEF:SemanticMapGenerator:Class] if __name__ == "__main__": parser = argparse.ArgumentParser(description="Generate Semantic Map and Compliance Reports") parser.add_argument("--agent-report", action="store_true", help="Output JSON report for AI agents") args = parser.parse_args() generator = SemanticMapGenerator(PROJECT_ROOT) generator.run() if args.agent_report: generator._print_agent_report() # [/DEF:generate_semantic_map:Module]