semantic update

This commit is contained in:
2026-02-24 21:08:12 +03:00
parent 7a12ed0931
commit 95ae9c6af1
32 changed files with 60376 additions and 59911 deletions

View File

@@ -1,9 +1,10 @@
# [DEF:generate_semantic_map:Module]
#
# @TIER: CRITICAL
# @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
# @PURPOSE: Scans the codebase to generate a Semantic Map, Module Map, and Compliance Report based on the System Standard.
# @LAYER: DevOps/Tooling
# @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
@@ -262,7 +263,7 @@ class SemanticEntity:
# 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" if is_python else "console.log with [ID][STATE]"
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,
@@ -296,13 +297,17 @@ class SemanticEntity:
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 * 0.3
score -= warnings * 0.1
score -= errors * error_penalty
score -= warnings * warning_penalty
# Check mandatory tags
required = TIER_MANDATORY_TAGS.get(tier, {}).get(self.type, [])
@@ -314,7 +319,8 @@ class SemanticEntity:
found_count += 1
break
if found_count < len(required):
score -= 0.2 * (1 - (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]
@@ -336,7 +342,8 @@ def get_patterns(lang: str) -> Dict[str, Pattern]:
"tag": re.compile(r"#\s*@(?P<tag>[A-Z_]+):\s*(?P<value>.*)"),
"relation": re.compile(r"#\s*@RELATION:\s*(?P<type>\w+)\s*->\s*(?P<target>.*)"),
"func_def": re.compile(r"^\s*(async\s+)?def\s+(?P<name>\w+)"),
"belief_scope": re.compile(r"with\s+(\w+\.)?belief_scope\("),
"belief_scope": re.compile(r"with\s+(\w+\.)?belief_scope\(|@believed\("),
"molecular_log": re.compile(r"logger\.(explore|reason|reflect)\("),
}
else:
return {
@@ -348,7 +355,7 @@ def get_patterns(lang: str) -> Dict[str, Pattern]:
"jsdoc_tag": re.compile(r"\*\s*@(?P<tag>[a-zA-Z]+)\s+(?P<value>.*)"),
"relation": re.compile(r"//\s*@RELATION:\s*(?P<type>\w+)\s*->\s*(?P<target>.*)"),
"func_def": re.compile(r"^\s*(export\s+)?(async\s+)?function\s+(?P<name>\w+)"),
"console_log": re.compile(r"console\.log\s*\(\s*['\"]\[[\w_]+\]\[[\w_]+\]"),
"console_log": re.compile(r"console\.log\s*\(\s*['\"`]\[[\w_]+\]\[[A-Za-z0-9_:]+\]"),
# Svelte-specific patterns
"export_let": re.compile(r"export\s+let\s+(?P<name>\w+)(?:\s*:\s*(?P<type>[\w\[\]|<>]+))?(?:\s*=\s*(?P<default>[^;]+))?"),
"create_event_dispatcher": re.compile(r"createEventDispatcher\s*<\s*\{\s*(?P<events>[^}]+)\s*\}\s*\>"),
@@ -609,8 +616,10 @@ def parse_file(full_path: str, rel_path: str, lang: str) -> Tuple[List[SemanticE
current.tags[tag_name] = tag_value
# Check for belief scope in implementation
if lang == "python" and "belief_scope" in patterns:
if patterns["belief_scope"].search(line):
if lang == "python":
if "belief_scope" in patterns and patterns["belief_scope"].search(line):
current.has_belief_scope = True
elif "molecular_log" in patterns and patterns["molecular_log"].search(line):
current.has_belief_scope = True
# Check for console.log belief state in Svelte
@@ -803,26 +812,39 @@ class SemanticMapGenerator:
with belief_scope("_process_file_results"):
total_score = 0
count = 0
module_max_tier = Tier.TRIVIAL
# [DEF:validate_recursive:Function]
# @TIER: STANDARD
# @PURPOSE: Recursively validates a list of entities.
# @PRE: ent_list is a list of SemanticEntity objects.
# @POST: All entities and their children are validated.
# @PURPOSE: Calculate score and determine module's max tier for weighted global score
# @PRE: Entities exist
# @POST: Entities are validated
def validate_recursive(ent_list):
with belief_scope("validate_recursive"):
nonlocal total_score, count
nonlocal total_score, count, module_max_tier
for e in ent_list:
e.validate()
total_score += e.get_score()
count += 1
# Determine dominant tier for file
e_tier = e.get_tier()
if e_tier == Tier.CRITICAL:
module_max_tier = Tier.CRITICAL
elif e_tier == Tier.STANDARD and module_max_tier != Tier.CRITICAL:
module_max_tier = Tier.STANDARD
validate_recursive(e.children)
# [/DEF:validate_recursive:Function]
validate_recursive(entities)
self.entities.extend(entities)
self.file_scores[rel_path] = (total_score / count) if count > 0 else 0.0
# Store both the score and the dominating tier for weighted global calculation
file_score = (total_score / count) if count > 0 else 0.0
self.file_scores[rel_path] = {"score": file_score, "tier": module_max_tier}
# [/DEF:_process_file_results:Function]
# [DEF:_generate_artifacts:Function]
@@ -860,7 +882,19 @@ class SemanticMapGenerator:
os.makedirs(REPORTS_DIR, exist_ok=True)
total_files = len(self.file_scores)
avg_score = sum(self.file_scores.values()) / total_files if total_files > 0 else 0
total_weighted_score = 0
total_weight = 0
for file_path, data in self.file_scores.items():
tier = data["tier"]
score = data["score"]
weight = 3 if tier == Tier.CRITICAL else (2 if tier == Tier.STANDARD else 1)
total_weighted_score += score * weight
total_weight += weight
avg_score = total_weighted_score / total_weight if total_weight > 0 else 0
# Count issues by severity
error_count = len([i for i in self.global_issues if i.severity == Severity.ERROR])
@@ -884,12 +918,19 @@ class SemanticMapGenerator:
f.write("| File | Score | Tier | Issues |\n")
f.write("|------|-------|------|--------|\n")
sorted_files = sorted(self.file_scores.items(), key=lambda x: x[1])
# Sort logically: Critical first, then by score
sorted_files = sorted(self.file_scores.items(), key=lambda x: (
0 if x[1]["tier"] == Tier.CRITICAL else (1 if x[1]["tier"] == Tier.STANDARD else 2),
x[1]["score"]
))
for file_path, score in sorted_files:
for file_path, data in sorted_files:
score = data["score"]
issues = []
tier = "N/A"
self._collect_issues(self.entities, file_path, issues, tier)
# Override Display Tier with the dominant tier we computed
tier = data["tier"].value
status_icon = "🟢" if score == 1.0 else "🟡" if score > 0.5 else "🔴"
issue_text = "<br>".join([f"{'🔴' if i.severity == Severity.ERROR else '🟡'} {i.message}" for i in issues[:3]])
@@ -1024,12 +1065,13 @@ class SemanticMapGenerator:
# @PRE: file_path is a valid relative path.
# @POST: Returns a module path string.
def _get_module_path(file_path: str) -> str:
# Convert file path to module-like path
parts = file_path.replace(os.sep, '/').split('/')
# Remove filename
if len(parts) > 1:
return '/'.join(parts[:-1])
return 'root'
with belief_scope("_get_module_path"):
# Convert file path to module-like path
parts = file_path.replace(os.sep, '/').split('/')
# Remove filename
if len(parts) > 1:
return '/'.join(parts[:-1])
return 'root'
# [/DEF:_get_module_path:Function]
# [DEF:_collect_all_entities:Function]
@@ -1038,9 +1080,10 @@ class SemanticMapGenerator:
# @PRE: entity list is valid.
# @POST: Returns flat list of all entities with their hierarchy.
def _collect_all_entities(entities: List[SemanticEntity], result: List[Tuple[str, SemanticEntity]]):
for e in entities:
result.append((_get_module_path(e.file_path), e))
_collect_all_entities(e.children, result)
with belief_scope("_collect_all_entities"):
for e in entities:
result.append((_get_module_path(e.file_path), e))
_collect_all_entities(e.children, result)
# [/DEF:_collect_all_entities:Function]
# Collect all entities