код написан
This commit is contained in:
@@ -97,25 +97,28 @@ 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"],
|
||||
"Component": ["PURPOSE", "LAYER", "SEMANTICS", "TIER", "INVARIANT", "UX_STATE", "UX_FEEDBACK", "UX_RECOVERY", "UX_REATIVITY"],
|
||||
"Function": ["PURPOSE", "PRE", "POST", "TEST_CONTRACT", "TEST_FIXTURE", "TEST_EDGE", "TEST_INVARIANT"],
|
||||
"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"]
|
||||
"Store": ["PURPOSE", "TIER", "INVARIANT"],
|
||||
"Block": ["PURPOSE", "TIER"]
|
||||
},
|
||||
Tier.STANDARD: {
|
||||
"Module": ["PURPOSE", "LAYER", "SEMANTICS", "TIER"],
|
||||
"Component": ["PURPOSE", "LAYER", "SEMANTICS", "TIER", "UX_STATE"],
|
||||
"Function": ["PURPOSE", "PRE", "POST"],
|
||||
"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"]
|
||||
"Store": ["PURPOSE", "TIER"],
|
||||
"Block": ["PURPOSE"]
|
||||
},
|
||||
Tier.TRIVIAL: {
|
||||
"Module": ["PURPOSE"],
|
||||
"Component": ["PURPOSE"],
|
||||
"Function": ["PURPOSE"],
|
||||
"Class": ["PURPOSE"],
|
||||
"Store": ["PURPOSE"]
|
||||
"Store": ["PURPOSE"],
|
||||
"Block": ["PURPOSE"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,6 +181,9 @@ class SemanticEntity:
|
||||
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]
|
||||
@@ -274,10 +280,13 @@ class SemanticEntity:
|
||||
required = TIER_MANDATORY_TAGS.get(tier, {}).get(self.type, [])
|
||||
for req_tag in required:
|
||||
found = False
|
||||
for existing_tag in self.tags:
|
||||
if existing_tag.upper() == req_tag:
|
||||
found = True
|
||||
break
|
||||
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(
|
||||
@@ -323,6 +332,34 @@ class SemanticEntity:
|
||||
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()
|
||||
@@ -358,10 +395,15 @@ class SemanticEntity:
|
||||
if required:
|
||||
found_count = 0
|
||||
for req_tag in required:
|
||||
for existing_tag in self.tags:
|
||||
if existing_tag.upper() == req_tag:
|
||||
found_count += 1
|
||||
break
|
||||
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
|
||||
@@ -381,27 +423,29 @@ 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<name>[\w\.]+):(?P<type>\w+)\]"),
|
||||
"anchor_end": re.compile(r"#\s*\[/DEF:(?P<name>[\w\.]+):(?P<type>\w+)\]"),
|
||||
"anchor_start": re.compile(r"#\s*\[DEF:(?P<name>[-\w\.]+):(?P<type>\w+)\]"),
|
||||
"anchor_end": re.compile(r"#\s*\[/DEF:(?P<name>[-\w\.]+):(?P<type>\w+)\]"),
|
||||
"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>.*)"),
|
||||
"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\(|@believed\("),
|
||||
"molecular_log": re.compile(r"logger\.(explore|reason|reflect)\("),
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"html_anchor_start": re.compile(r"<!--\s*\[DEF:(?P<name>[\w\.]+):(?P<type>\w+)\]\s*-->"),
|
||||
"html_anchor_end": re.compile(r"<!--\s*\[/DEF:(?P<name>[\w\.]+):(?P<type>\w+)\]\s*-->"),
|
||||
"js_anchor_start": re.compile(r"//\s*\[DEF:(?P<name>[\w\.]+):(?P<type>\w+)\]"),
|
||||
"js_anchor_end": re.compile(r"//\s*\[/DEF:(?P<name>[\w\.]+):(?P<type>\w+)\]"),
|
||||
"html_anchor_start": re.compile(r"<!--\s*\[DEF:(?P<name>[-\w\.]+):(?P<type>\w+)\]\s*-->"),
|
||||
"html_anchor_end": re.compile(r"<!--\s*\[/DEF:(?P<name>[-\w\.]+):(?P<type>\w+)\]\s*-->"),
|
||||
"js_anchor_start": re.compile(r"//\s*\[DEF:(?P<name>[-\w\.]+):(?P<type>\w+)\]"),
|
||||
"js_anchor_end": re.compile(r"//\s*\[/DEF:(?P<name>[-\w\.]+):(?P<type>\w+)\]"),
|
||||
"html_tag": re.compile(r"@(?P<tag>[A-Z_]+):\s*(?P<value>.*)"),
|
||||
"jsdoc_tag": re.compile(r"\*\s*@(?P<tag>[A-Za-z_]+)\s*:?\s*(?P<value>.*)"),
|
||||
"relation": re.compile(r"//\s*@RELATION:\s*(?P<type>\w+)\s*->\s*(?P<target>.*)"),
|
||||
"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_]+\]\[[A-Za-z0-9_:]+\]"),
|
||||
"console_log": re.compile(r"console\.(info|warn|debug)\s*\(\s*['\"`]\[[\w\.-]+\]\[(EXPLORE|REASON|REFLECT|[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>[^;]+))?"),
|
||||
"reactive_label": re.compile(r"^\s*\$:\s*"),
|
||||
"runes_usage": re.compile(r"\$(state|derived|effect|props)\s*\("),
|
||||
"create_event_dispatcher": re.compile(r"createEventDispatcher\s*<\s*\{\s*(?P<events>[^}]+)\s*\}\s*\>"),
|
||||
"dispatch_call": re.compile(r"dispatch\s*\(\s*['\"](?P<event>\w+)['\"]"),
|
||||
"store_subscription": re.compile(r"\$(?P<store>\w+)"),
|
||||
@@ -667,10 +711,16 @@ def parse_file(full_path: str, rel_path: str, lang: str) -> Tuple[List[SemanticE
|
||||
elif "molecular_log" in patterns and patterns["molecular_log"].search(line):
|
||||
current.has_belief_scope = True
|
||||
|
||||
# Check for console.log belief state in Svelte
|
||||
if lang == "svelte_js" and "console_log" in patterns:
|
||||
if patterns["console_log"].search(line):
|
||||
# Check for console logging + forbidden/required Svelte reactivity signals
|
||||
if lang == "svelte_js":
|
||||
if "console_log" in patterns and patterns["console_log"].search(line):
|
||||
current.has_console_log = True
|
||||
if "export_let" in patterns and patterns["export_let"].search(line):
|
||||
current.has_export_let = True
|
||||
if "reactive_label" in patterns and patterns["reactive_label"].search(line):
|
||||
current.has_reactive_label = True
|
||||
if "runes_usage" in patterns and patterns["runes_usage"].search(line):
|
||||
current.has_runes = True
|
||||
|
||||
# End of file check
|
||||
if stack:
|
||||
@@ -1036,6 +1086,7 @@ class SemanticMapGenerator:
|
||||
elif entity.type == "Function": icon = "ƒ"
|
||||
elif entity.type == "Class": icon = "ℂ"
|
||||
elif entity.type == "Store": icon = "🗄️"
|
||||
elif entity.type == "Block": icon = "▦"
|
||||
|
||||
tier_badge = ""
|
||||
tier = entity.get_tier()
|
||||
|
||||
Reference in New Issue
Block a user