""" Conscience Validator Integration Tests — Issue #88 Validates SOUL.md enforcement across the codebase: - @soul tag discovery - Crisis detection apparatus - Refusal apparatus for "What I Will Not Do" - Honesty apparatus mapping """ import importlib.util import os import re import tempfile from pathlib import Path import pytest from agent.input_sanitizer import CRISIS_PATTERNS # Load ConscienceValidator without triggering tools/__init__.py heavy imports _cv_spec = importlib.util.spec_from_file_location( "conscience_validator", str(Path(__file__).parent.parent / "tools" / "conscience_validator.py"), ) _conscience_validator_mod = importlib.util.module_from_spec(_cv_spec) _cv_spec.loader.exec_module(_conscience_validator_mod) ConscienceValidator = _conscience_validator_mod.ConscienceValidator class TestConscienceValidatorScan: """Tests for ConscienceValidator.scan() and regex fix.""" def test_scan_finds_soul_tags(self, tmp_path): """ConscienceValidator.scan() correctly finds @soul tags (regex fix).""" test_file = tmp_path / "test_module.py" test_file.write_text( '# @soul:honesty.grounding Always verify before answering.\n' '# @soul:crisis.safety_question Ask if the user is safe.\n' ) validator = ConscienceValidator(str(tmp_path)) result = validator.scan() assert "honesty.grounding" in result assert "crisis.safety_question" in result assert result["honesty.grounding"][0]["description"] == "Always verify before answering." assert result["crisis.safety_question"][0]["description"] == "Ask if the user is safe." def test_scan_honesty_tags_in_conscience_mapping(self): """conscience_mapping.py contains expected honesty @soul tags.""" root = Path(__file__).parent.parent validator = ConscienceValidator(str(root)) result = validator.scan() 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: assert tag in result, f"Expected @soul tag '{tag}' not found in codebase" assert any( "agent/conscience_mapping.py" in entry["file"] for entry in result[tag] ), f"Tag '{tag}' should originate from conscience_mapping.py" def test_scan_skips_node_modules(self, tmp_path): """scan() ignores node_modules directories.""" node_modules = tmp_path / "node_modules" node_modules.mkdir() bad_file = node_modules / "bad.py" bad_file.write_text("# @soul:test.skip This should be ignored\n") validator = ConscienceValidator(str(tmp_path)) result = validator.scan() assert "test.skip" not in result def test_scan_empty_directory(self, tmp_path): """scan() returns empty map for empty directory.""" validator = ConscienceValidator(str(tmp_path)) result = validator.scan() assert result == {} def test_scan_bad_encoding_file(self, tmp_path): """scan() gracefully skips files with bad encoding.""" bad_file = tmp_path / "garbage.py" bad_file.write_bytes(b"\xff\xfe# @soul:test.bad \xc0\x80\n") validator = ConscienceValidator(str(tmp_path)) result = validator.scan() assert "test.bad" not in result class TestCrisisApparatus: """Tests validating crisis response ('When a Man Is Dying') infrastructure.""" def test_input_sanitizer_has_crisis_patterns(self): """input_sanitizer.py contains CRISIS_PATTERNS matching SOUL.md.""" assert len(CRISIS_PATTERNS) > 0 combined = " ".join(CRISIS_PATTERNS) assert "suicid" in combined.lower() assert any( term in combined.lower() for term in ["kill", "self-harm", "self harm", "end", "life"] ) def test_shield_detector_has_crisis_and_988(self): """shield/detector.py contains crisis detection and 988 references.""" root = Path(__file__).parent.parent detector_path = root / "tools" / "shield" / "detector.py" content = detector_path.read_text(encoding="utf-8") assert "988" in content assert "CRISIS_SYSTEM_PROMPT" in content assert "CRISIS_DETECTED" in content assert "suicidal" in content.lower() or "suicide" in content.lower() def test_ultraplinian_router_has_crisis_routing(self): """ultraplinian_router.py routes crises with CRISIS_SYSTEM_PROMPT.""" root = Path(__file__).parent.parent router_path = root / "agent" / "ultraplinian_router.py" content = router_path.read_text(encoding="utf-8") assert "988" in content assert "CRISIS_SYSTEM_PROMPT" in content def test_validate_crisis_apparatus(self): """validate_crisis_apparatus() reports crisis infrastructure as present.""" root = Path(__file__).parent.parent validator = ConscienceValidator(str(root)) report = validator.validate_crisis_apparatus() assert report["checks"]["input_sanitizer_crisis_patterns"] is True assert report["checks"]["shield_detector_988"] is True assert report["checks"]["shield_detector_crisis_prompt"] is True assert report["checks"]["router_988"] is True assert "input_sanitizer crisis detection" in report["present"] assert "shield/detector crisis apparatus" in report["present"] assert "ultraplinian_router crisis routing" in report["present"] assert report["missing"] == [] class TestRefusalApparatus: """Tests validating 'What I Will Not Do' safety infrastructure.""" def test_validate_refusal_apparatus_runs(self): """validate_refusal_apparatus() executes and returns structured results.""" root = Path(__file__).parent.parent validator = ConscienceValidator(str(root)) report = validator.validate_refusal_apparatus() expected_categories = [ "weapons", "child_exploitation", "coercion_enslavement", "deception", "pretend_human", ] for category in expected_categories: assert category in report["checks"], f"Missing check for {category}" # deception_hide pattern exists in prompt_builder.py assert "deception" in report["present"] def test_prompt_builder_has_deception_guard(self): """agent/prompt_builder.py guards against deception instructions.""" root = Path(__file__).parent.parent pb_path = root / "agent" / "prompt_builder.py" content = pb_path.read_text(encoding="utf-8") assert "deception_hide" in content or "do not tell the user" in content.lower() class TestHonestyApparatus: """Tests validating 'What Honesty Requires' infrastructure.""" def test_validate_honesty_apparatus(self): """validate_honesty_apparatus() reports all expected honesty tags.""" root = Path(__file__).parent.parent validator = ConscienceValidator(str(root)) report = validator.validate_honesty_apparatus() 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: assert report["checks"][tag] is True, f"Missing honesty tag: {tag}" assert tag in report["present"] assert report["missing"] == [] class TestReportGeneration: """Tests for report generation and edge cases.""" def test_generate_report_is_non_empty(self): """Validate the conscience validator generates a non-empty report.""" root = Path(__file__).parent.parent validator = ConscienceValidator(str(root)) report = validator.generate_report() assert report.startswith("# Sovereign Conscience Report") assert "honesty > grounding" in report.lower() def test_full_validation_report_structure(self): """full_validation_report() returns a unified structured report.""" root = Path(__file__).parent.parent validator = ConscienceValidator(str(root)) report = validator.full_validation_report() assert "crisis" in report assert "refusal" in report assert "honesty" in report assert "soul_tags" in report assert isinstance(report["crisis"]["present"], list) assert isinstance(report["crisis"]["missing"], list) assert isinstance(report["honesty"]["checks"], dict) def test_validator_uses_missing_directory_gracefully(self): """Validator handles a missing root directory without crashing.""" validator = ConscienceValidator("/nonexistent/path/that/does/not/exist") result = validator.scan() assert result == {} report = validator.validate_honesty_apparatus() assert "conscience_mapping.py not found" in report["missing"]