#!/usr/bin/env python3 """ LogicValidator – prüft Core-Logik für Konsistenz, Boundaries, Transitionen """ import json import os import sys from datetime import datetime, timezone PATHS = { "state": os.path.expanduser("~/natiris/core/natiris_full_state.json"), "config": os.path.expanduser("~/natiris/config/character_genesis.json"), "output": os.path.expanduser("~/natiris/core/logic_validation.json"), } def clamp(val, lo=0.0, hi=10.0): return max(lo, min(hi, float(val))) def clamp01(val): return max(0.0, min(1.0, float(val))) def validate(state, config): errors = [] warnings = [] # Core-Values bounds core = state.get("core_state", {}) emotion = state.get("modules", {}).get("Emotion", {}) maturity = state.get("modules", {}).get("Maturity", {}) bond = state.get("modules", {}).get("Bond", {}) # 1. Mood bounds if not (0 <= core.get("mood", 5) <= 10): errors.append("mood außerhalb 0-10") # 2. loneliness bounds if not (0 <= core.get("loneliness", 2) <= 10): errors.append("loneliness außerhalb 0-10") # 3. Bond-Logik if bond.get("exclusivity_active") and bond.get("bonded_to") is None: errors.append("exclusivity ohne bonded_to") if bond.get("bonded_to") and not bond.get("exclusivity_active"): warnings.append("bonded_to ohne exclusivity – nicht notwendig, möglicherweise gewünscht") # 4. Maturity Bias bounds if not (0 <= maturity.get("stability_bias", 0) <= 1): errors.append("stability_bias außerhalb 0-1") if not (0 <= maturity.get("dependency_bias", 0) <= 1): errors.append("dependency_bias außerhalb 0-1") # 5. Regression Factor if not (0 <= maturity.get("regression_factor", 0) <= 1): errors.append("regression_factor außerhalb 0-1") # 6. Bond-Jealousy-Risk if not (0 <= bond.get("jealousy_risk", 0) <= 1): errors.append("jealousy_risk außerhalb 0-1") return errors, warnings def test_transitions(state, config): tests = [] # Simulation: loneliness hoch → mood sinkt test_state = state.copy() test_state["core_state"] = state.get("core_state", {}).copy() test_state["core_state"]["loneliness"] = 8 test_state["modules"] = state.get("modules", {}).copy() test_state["modules"]["Emotion"] = state.get("modules", {}).get("Emotion", {}).copy() # mood_delta sollte sinken wenn loneliness hoch mood_delta_bound = clamp((test_state["core_state"]["loneliness"] - 5) * -0.1) if mood_delta_bound < -0.2: tests.append("✅ Loneliness-Test (hoch → mood sinkt)") # Bond-Test if test_state["modules"].get("Bond", {}).get("exclusivity_active"): tests.append("✅ Bond-Test (exklusiv aktiv)") return tests def main(): try: with open(PATHS["state"]) as f: state = json.load(f) except Exception as e: print(f"❌ State nicht ladbar: {e}") sys.exit(1) with open(PATHS["config"]) as f: config = json.load(f) errors, warnings = validate(state, config) tests = test_transitions(state, config) if errors: for e in errors: print(f"❌ {e}") else: print("✅ Alle Bounds OK") if warnings: for w in warnings: print(f"⚠️ {w}") for t in tests: print(t) result = { "timestamp": datetime.now(timezone.utc).isoformat(), "errors": errors, "warnings": warnings, "tests_passed": tests } with open(PATHS["output"], "w") as f: json.dump(result, f, indent=2) if __name__ == "__main__": main()