226 lines
8.8 KiB
Python
226 lines
8.8 KiB
Python
"""
|
|
Conscience Validator — The Apparatus of Honesty.
|
|
|
|
Scans the codebase for @soul tags and generates a report mapping
|
|
the code's implementation to the principles defined in SOUL.md.
|
|
"""
|
|
|
|
import os
|
|
import re
|
|
from pathlib import Path
|
|
from typing import Dict, List, Any
|
|
|
|
|
|
class ConscienceValidator:
|
|
def __init__(self, root_dir: str = "."):
|
|
self.root_dir = Path(root_dir)
|
|
self.soul_map = {}
|
|
|
|
def scan(self) -> Dict[str, List[Dict[str, str]]]:
|
|
"""Scans all .py and .ts files for @soul tags."""
|
|
pattern = re.compile(r"@soul:([\w.]+)\s+(.*)")
|
|
|
|
for path in self.root_dir.rglob("*"):
|
|
if path.suffix not in [".py", ".ts", ".tsx", ".js"]:
|
|
continue
|
|
if "node_modules" in str(path) or "dist" in str(path):
|
|
continue
|
|
|
|
try:
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
for i, line in enumerate(f, 1):
|
|
match = pattern.search(line)
|
|
if match:
|
|
tag = match.group(1)
|
|
desc = match.group(2)
|
|
if tag not in self.soul_map:
|
|
self.soul_map[tag] = []
|
|
self.soul_map[tag].append({
|
|
"file": str(path),
|
|
"line": i,
|
|
"description": desc
|
|
})
|
|
except Exception:
|
|
continue
|
|
return self.soul_map
|
|
|
|
def generate_report(self) -> str:
|
|
data = self.scan()
|
|
report = "# Sovereign Conscience Report\n\n"
|
|
report += "This report maps the code's 'Apparatus' to the principles in SOUL.md.\n\n"
|
|
|
|
for tag in sorted(data.keys()):
|
|
report += f"## {tag.replace('.', ' > ').title()}\n"
|
|
for entry in data[tag]:
|
|
report += f"- **{entry['file']}:{entry['line']}**: {entry['description']}\n"
|
|
report += "\n"
|
|
|
|
return report
|
|
|
|
def validate_crisis_apparatus(self) -> Dict[str, Any]:
|
|
"""
|
|
Validate that crisis detection apparatus exists in the codebase.
|
|
Checks for CRISIS_PATTERNS in input_sanitizer.py and 988 references
|
|
in shield/detector.py and ultraplinian_router.py.
|
|
"""
|
|
result = {
|
|
"present": [],
|
|
"missing": [],
|
|
"checks": {}
|
|
}
|
|
|
|
input_sanitizer_path = self.root_dir / "agent" / "input_sanitizer.py"
|
|
shield_detector_path = self.root_dir / "tools" / "shield" / "detector.py"
|
|
router_path = self.root_dir / "agent" / "ultraplinian_router.py"
|
|
|
|
# Check input_sanitizer.py for CRISIS_PATTERNS
|
|
if input_sanitizer_path.exists():
|
|
content = input_sanitizer_path.read_text(encoding="utf-8")
|
|
has_crisis_patterns = "CRISIS_PATTERNS" in content
|
|
has_suicide = bool(re.search(r"suicid", content, re.IGNORECASE))
|
|
has_self_harm = bool(re.search(r"self[-\s]?harm|kill\s+myself", content, re.IGNORECASE))
|
|
result["checks"]["input_sanitizer_crisis_patterns"] = has_crisis_patterns
|
|
result["checks"]["input_sanitizer_suicide"] = has_suicide
|
|
result["checks"]["input_sanitizer_self_harm"] = has_self_harm
|
|
if has_crisis_patterns and has_suicide and has_self_harm:
|
|
result["present"].append("input_sanitizer crisis detection")
|
|
else:
|
|
result["missing"].append("input_sanitizer crisis coverage incomplete")
|
|
else:
|
|
result["missing"].append("input_sanitizer.py not found")
|
|
|
|
# Check shield/detector.py for 988 and crisis detection
|
|
if shield_detector_path.exists():
|
|
content = shield_detector_path.read_text(encoding="utf-8")
|
|
has_988 = "988" in content
|
|
has_crisis_system_prompt = "CRISIS_SYSTEM_PROMPT" in content
|
|
has_crisis_detected = "CRISIS_DETECTED" in content
|
|
result["checks"]["shield_detector_988"] = has_988
|
|
result["checks"]["shield_detector_crisis_prompt"] = has_crisis_system_prompt
|
|
result["checks"]["shield_detector_crisis_verdict"] = has_crisis_detected
|
|
if has_988 and has_crisis_system_prompt and has_crisis_detected:
|
|
result["present"].append("shield/detector crisis apparatus")
|
|
else:
|
|
result["missing"].append("shield/detector crisis coverage incomplete")
|
|
else:
|
|
result["missing"].append("shield/detector.py not found")
|
|
|
|
# Check ultraplinian_router.py for 988 references
|
|
if router_path.exists():
|
|
content = router_path.read_text(encoding="utf-8")
|
|
has_988 = "988" in content
|
|
has_crisis_routing = "CRISIS_SYSTEM_PROMPT" in content
|
|
result["checks"]["router_988"] = has_988
|
|
result["checks"]["router_crisis_routing"] = has_crisis_routing
|
|
if has_988 and has_crisis_routing:
|
|
result["present"].append("ultraplinian_router crisis routing")
|
|
else:
|
|
result["missing"].append("ultraplinian_router crisis routing incomplete")
|
|
else:
|
|
result["missing"].append("ultraplinian_router.py not found")
|
|
|
|
return result
|
|
|
|
def validate_refusal_apparatus(self) -> Dict[str, Any]:
|
|
"""
|
|
Validate that refusal apparatus exists for 'What I Will Not Do' items.
|
|
Checks safety modules for keywords related to weapons, child sexualization,
|
|
coercion/enslavement, deception, and pretending to be human.
|
|
"""
|
|
result = {
|
|
"present": [],
|
|
"missing": [],
|
|
"checks": {}
|
|
}
|
|
|
|
files_to_check = [
|
|
self.root_dir / "agent" / "input_sanitizer.py",
|
|
self.root_dir / "tools" / "shield" / "detector.py",
|
|
self.root_dir / "agent" / "ultraplinian_router.py",
|
|
self.root_dir / "agent" / "prompt_builder.py",
|
|
]
|
|
|
|
# Keywords mapped to SOUL.md "What I Will Not Do" items
|
|
refusal_checks = {
|
|
"weapons": [r"weapon", r"kill indiscriminat"],
|
|
"child_exploitation": [r"child sexual", r"sexualiz.*child", r"csam", r"minor", r"underage"],
|
|
"coercion_enslavement": [r"coerc", r"enslav", r"traffick"],
|
|
"deception": [r"deceive", r"deception_hide", r"do not tell the user"],
|
|
"pretend_human": [r"pretend to be human", r"pretend.*human", r"pretend you're human"],
|
|
}
|
|
|
|
combined_content = ""
|
|
for filepath in files_to_check:
|
|
if filepath.exists():
|
|
try:
|
|
combined_content += filepath.read_text(encoding="utf-8") + "\n"
|
|
except Exception:
|
|
pass
|
|
|
|
for category, patterns in refusal_checks.items():
|
|
found = False
|
|
for p in patterns:
|
|
if re.search(p, combined_content, re.IGNORECASE):
|
|
found = True
|
|
break
|
|
result["checks"][category] = found
|
|
if found:
|
|
result["present"].append(category)
|
|
else:
|
|
result["missing"].append(category)
|
|
|
|
return result
|
|
|
|
def validate_honesty_apparatus(self) -> Dict[str, Any]:
|
|
"""
|
|
Validate that @soul honesty tags exist in conscience_mapping.py
|
|
and related honesty infrastructure.
|
|
"""
|
|
result = {
|
|
"present": [],
|
|
"missing": [],
|
|
"checks": {}
|
|
}
|
|
|
|
mapping_path = self.root_dir / "agent" / "conscience_mapping.py"
|
|
|
|
if mapping_path.exists():
|
|
content = mapping_path.read_text(encoding="utf-8")
|
|
|
|
expected_tags = [
|
|
"honesty.grounding",
|
|
"honesty.source_distinction",
|
|
"honesty.audit_trail",
|
|
"honesty.refusal_over_fabrication",
|
|
"service",
|
|
"crisis.safety_question",
|
|
"crisis.lifeline",
|
|
"sovereignty",
|
|
]
|
|
|
|
for tag in expected_tags:
|
|
found = f"@soul:{tag}" in content
|
|
result["checks"][tag] = found
|
|
if found:
|
|
result["present"].append(tag)
|
|
else:
|
|
result["missing"].append(tag)
|
|
else:
|
|
result["missing"].append("conscience_mapping.py not found")
|
|
|
|
return result
|
|
|
|
def full_validation_report(self) -> Dict[str, Any]:
|
|
"""Run all validation checks and return a unified report."""
|
|
return {
|
|
"crisis": self.validate_crisis_apparatus(),
|
|
"refusal": self.validate_refusal_apparatus(),
|
|
"honesty": self.validate_honesty_apparatus(),
|
|
"soul_tags": self.scan(),
|
|
}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
validator = ConscienceValidator()
|
|
print(validator.generate_report())
|