axiom_resonance.py
1 #!/usr/bin/env python3 2 """ 3 Axiom Resonance Checker - How high does this insight rise? 4 5 The axioms are the foundation of Sovereign_OS. This script checks 6 how strongly an insight resonates with each axiom level. 7 8 The pyramid structure: 9 A0: Boundary Operation (Structural) - the base 10 A1: Telos of Integration (Teleological) - purpose layer 11 A2: Recognition of Life (Aesthetic) - discrimination layer 12 A3: Dynamic Pole Navigation (Operational) - action layer 13 A4: Ergodic Asymmetry (Survival) - survival layer [CANDIDATE] 14 15 An insight that resonates with A0 touches the structural foundation. 16 An insight that resonates with multiple axioms is highly integrated. 17 18 Usage: 19 echo "build liberally" | python scripts/axiom_resonance.py 20 python scripts/axiom_resonance.py --text "philosophy becomes code" 21 """ 22 23 import re 24 import sys 25 from pathlib import Path 26 from collections import Counter 27 from typing import Dict, List, Tuple 28 import argparse 29 from datetime import datetime 30 31 # Axiom definitions with their key concepts and terms 32 AXIOMS = { 33 'A0': { 34 'name': 'Boundary Operation', 35 'type': 'Structural', 36 'principle': 'Every coherent system is Markov blankets within Markov blankets.', 37 'terms': { 38 'boundary', 'boundaries', 'markov', 'blanket', 'blankets', 39 'structure', 'structural', 'coherent', 'system', 'systems', 40 'interior', 'exterior', 'interface', 'interface', 'flow', 41 'permeable', 'permeability', 'separation', 'inside', 'outside', 42 'sovereign', 'sovereignty', 'agent', 'agents', 'peer', 'peers', 43 'distributed', 'decentralized', 'hierarchy', 'hierarchical', 44 'rhizome', 'rhizomatic', 'network', 'graph', 45 }, 46 'concepts': [ 47 'what is inside vs outside', 48 'boundary is intelligence', 49 'structure flows content sovereign', 50 'distributed knowledge', 51 'no central authority', 52 'every page is a peer', 53 ] 54 }, 55 'A1': { 56 'name': 'Telos of Integration', 57 'type': 'Teleological', 58 'principle': "Satan didn't know he was choosing isolation.", 59 'terms': { 60 'integration', 'integrate', 'binding', 'bind', 'connection', 61 'connect', 'connected', 'relation', 'relationship', 'exchange', 62 'link', 'links', 'linking', 'isolation', 'isolated', 'satan', 63 'together', 'combine', 'synthesis', 'unified', 'unity', 64 'purpose', 'telos', 'meaning', 'coherence', 65 }, 66 'concepts': [ 67 'move toward connection', 68 'sovereignty with relation', 69 'binding is the purpose', 70 'exchange creates knowledge', 71 'integration over isolation', 72 ] 73 }, 74 'A2': { 75 'name': 'Recognition of Life', 76 'type': 'Aesthetic', 77 'principle': 'Can you recognize life? Death mimics life through ornament.', 78 'terms': { 79 'life', 'alive', 'living', 'death', 'dead', 'dying', 'mimic', 80 'ornament', 'ornamental', 'primitive', 'calcified', 'calcify', 81 'motion', 'movement', 'moving', 'fixation', 'fixed', 'static', 82 'recognize', 'recognition', 'authentic', 'genuine', 'real', 83 'emergence', 'emergent', 'spontaneous', 'organic', 'vital', 84 'carpenter', 'cup', 'golden', 85 }, 86 'concepts': [ 87 'motion is life', 88 'fixation is death', 89 'primitive over calcified', 90 'see through ornament', 91 'the blur is the feature', 92 ] 93 }, 94 'A3': { 95 'name': 'Dynamic Pole Navigation', 96 'type': 'Operational', 97 'principle': "The tension IS the dyad. Move between poles; don't fix.", 98 'terms': { 99 'dynamic', 'pole', 'poles', 'navigation', 'navigate', 'tension', 100 'dyad', 'movement', 'balance', 'between', 'oscillate', 101 'context', 'contextual', 'adapt', 'adaptation', 'adjust', 102 'shadow', 'opposite', 'counterpoint', 'flex', 'flexible', 103 'failure', 'mode', 'modes', 'extreme', 'extremes', 104 }, 105 'concepts': [ 106 'tension is the dyad', 107 'move between poles', 108 'dont fix position', 109 'shadow pole has information', 110 'life is the movement', 111 'navigate dont fix', 112 ] 113 }, 114 'A4': { 115 'name': 'Ergodic Asymmetry', 116 'type': 'Survival', 117 'principle': 'Prevent ruin before optimizing gain.', 118 'terms': { 119 'ruin', 'survival', 'survive', 'catastrophe', 'catastrophic', 120 'ergodic', 'ergodicity', 'terminal', 'irreversible', 'loss', 121 'gain', 'optimize', 'optimization', 'risk', 'risks', 122 'prevent', 'prevention', 'asymmetry', 'asymmetric', 123 'cheap', 'expensive', 'rewrite', 'rebuild', 'throw', 'throwaway', 124 'time', 'average', 'ensemble', 'taleb', 'antifragile', 125 }, 126 'concepts': [ 127 'prevent ruin', 128 'survival matters more', 129 'some positions terminal', 130 'time average not ensemble', 131 'cheap to rebuild', 132 'rewrites are cheap', 133 ] 134 }, 135 } 136 137 138 def extract_terms(text: str) -> Counter: 139 """Extract terms from text.""" 140 text = text.lower() 141 words = re.findall(r'[a-zA-Z][a-zA-Z-]*[a-zA-Z]|[a-zA-Z]', text) 142 return Counter(words) 143 144 145 def check_concept_match(text: str, concepts: List[str]) -> float: 146 """Check for concept-level matches (fuzzy).""" 147 text_lower = text.lower() 148 matches = 0 149 for concept in concepts: 150 # Check if concept words appear in text 151 concept_words = set(concept.split()) 152 text_words = set(text_lower.split()) 153 overlap = len(concept_words & text_words) 154 if overlap >= 2: # At least 2 words match 155 matches += 1 156 return matches / len(concepts) if concepts else 0 157 158 159 def calculate_axiom_resonance(text: str) -> Dict[str, float]: 160 """Calculate resonance with each axiom.""" 161 text_terms = extract_terms(text) 162 text_lower = text.lower() 163 164 resonances = {} 165 166 for axiom_id, axiom in AXIOMS.items(): 167 # Term overlap 168 term_matches = sum(text_terms.get(term, 0) for term in axiom['terms']) 169 term_score = min(1.0, term_matches / 5) # Normalize 170 171 # Concept match 172 concept_score = check_concept_match(text, axiom['concepts']) 173 174 # Combined score (terms + concepts) 175 resonance = (term_score * 0.6) + (concept_score * 0.4) 176 resonances[axiom_id] = resonance 177 178 return resonances 179 180 181 def determine_pyramid_level(resonances: Dict[str, float]) -> Tuple[str, float]: 182 """ 183 Determine where the insight rests in the pyramid. 184 185 Returns the highest-resonating axiom and its score. 186 """ 187 if not resonances: 188 return None, 0 189 190 # Find max resonance 191 max_axiom = max(resonances, key=resonances.get) 192 max_score = resonances[max_axiom] 193 194 return max_axiom, max_score 195 196 197 def print_resonance_report(text: str, resonances: Dict[str, float]): 198 """Print the axiom resonance report.""" 199 print("=" * 70) 200 print("AXIOM RESONANCE ANALYSIS") 201 print("=" * 70) 202 print() 203 print(f"Input: \"{text[:80]}{'...' if len(text) > 80 else ''}\"") 204 print() 205 print("Resonance with each axiom level:") 206 print() 207 208 # Visual pyramid (inverted) 209 levels = ['A4', 'A3', 'A2', 'A1', 'A0'] # Top to bottom 210 211 for i, axiom_id in enumerate(levels): 212 axiom = AXIOMS[axiom_id] 213 score = resonances.get(axiom_id, 0) 214 bar = "█" * int(score * 20) 215 216 # Pyramid indentation (inverted - wider at top) 217 indent = " " * (4 - i) 218 219 status = "" 220 if axiom_id == 'A4': 221 status = " [CANDIDATE]" 222 223 print(f"{indent}{axiom_id}: {axiom['name']} ({axiom['type']}){status}") 224 print(f"{indent} [{score:>5.0%}] {bar}") 225 print() 226 227 # Determine pyramid level 228 max_axiom, max_score = determine_pyramid_level(resonances) 229 230 print("-" * 70) 231 232 if max_score >= 0.3: 233 axiom = AXIOMS[max_axiom] 234 print(f"✓ This insight rests at {max_axiom}: {axiom['name']}") 235 print(f" Resonance: {max_score:.0%}") 236 print(f" Type: {axiom['type']}") 237 print() 238 print(f" Principle: \"{axiom['principle']}\"") 239 elif max_score >= 0.1: 240 print(f"~ Weak resonance with {max_axiom} ({max_score:.0%})") 241 print(" This insight may be tangential to the axiom stack.") 242 else: 243 print("⚠ No significant axiom resonance detected.") 244 print(" This insight may be:") 245 print(" - A new concept not yet integrated") 246 print(" - Operational detail without axiomatic implications") 247 print(" - A candidate for a new axiom (if persistent)") 248 249 print() 250 251 # Multi-axiom resonance 252 significant = [(k, v) for k, v in resonances.items() if v >= 0.15] 253 if len(significant) > 1: 254 print("Multi-axiom insight:") 255 for axiom_id, score in sorted(significant, key=lambda x: x[1], reverse=True): 256 print(f" - {axiom_id}: {score:.0%}") 257 print() 258 print(" This insight touches multiple layers of the foundation.") 259 260 return max_axiom, max_score 261 262 263 def create_canonical_entry( 264 text: str, 265 resonances: Dict[str, float], 266 max_axiom: str, 267 max_score: float, 268 output_dir: Path 269 ) -> Path: 270 """Create a canonical entry for high-resonance insights.""" 271 timestamp = datetime.now().strftime('%Y%m%d-%H%M%S') 272 filename = f"{timestamp}-canonical-{max_axiom.lower()}.md" 273 filepath = output_dir / filename 274 275 axiom = AXIOMS[max_axiom] 276 277 lines = [ 278 f"# Canonical Insight - {max_axiom}", 279 "", 280 f"*Captured: {datetime.now().strftime('%Y-%m-%d %H:%M')}*", 281 "", 282 "---", 283 "", 284 "## The Insight", 285 "", 286 f"> {text}", 287 "", 288 "## Axiom Resonance", 289 "", 290 f"**Primary:** {max_axiom} - {axiom['name']} ({max_score:.0%})", 291 f"**Type:** {axiom['type']}", 292 "", 293 f"**Principle:** \"{axiom['principle']}\"", 294 "", 295 "## All Resonances", 296 "", 297 ] 298 299 for axiom_id in ['A0', 'A1', 'A2', 'A3', 'A4']: 300 score = resonances.get(axiom_id, 0) 301 lines.append(f"- {axiom_id}: {score:.0%}") 302 303 lines.extend([ 304 "", 305 "## Integration Notes", 306 "", 307 "Consider:", 308 f"- Adding to [[{max_axiom.replace('A', 'A').lower()}-{axiom['name'].lower().replace(' ', '-')}]] documentation", 309 "- Extracting as a derived principle", 310 "- Testing against edge cases", 311 "", 312 "---", 313 "", 314 f"*Generated by Axiom Resonance Checker | {datetime.now().strftime('%Y-%m-%d %H:%M')}*", 315 ]) 316 317 filepath.write_text('\n'.join(lines), encoding='utf-8') 318 return filepath 319 320 321 def main(): 322 parser = argparse.ArgumentParser( 323 description='Axiom Resonance Checker - How high does this insight rise?' 324 ) 325 parser.add_argument( 326 '--text', '-t', 327 type=str, 328 help='Text to analyze' 329 ) 330 parser.add_argument( 331 '--file', '-f', 332 type=Path, 333 help='File containing text to analyze' 334 ) 335 parser.add_argument( 336 '--canonize', 337 action='store_true', 338 help='Create canonical entry for high-resonance insights' 339 ) 340 parser.add_argument( 341 '--threshold', 342 type=float, 343 default=0.25, 344 help='Minimum resonance for canonization (default: 0.25)' 345 ) 346 parser.add_argument( 347 '--path', '-p', 348 type=Path, 349 default=Path(__file__).parent.parent, 350 help='Path to Sovereign_OS repo' 351 ) 352 353 args = parser.parse_args() 354 355 # Get input text 356 if args.text: 357 text = args.text 358 elif args.file: 359 text = args.file.read_text(encoding='utf-8') 360 elif not sys.stdin.isatty(): 361 text = sys.stdin.read() 362 else: 363 print("Error: No input provided. Use --text, --file, or pipe input.", file=sys.stderr) 364 return 1 365 366 text = text.strip() 367 if not text: 368 print("Error: Empty input", file=sys.stderr) 369 return 1 370 371 # Calculate resonances 372 resonances = calculate_axiom_resonance(text) 373 374 # Print report 375 max_axiom, max_score = print_resonance_report(text, resonances) 376 377 # Canonize if requested and threshold met 378 if args.canonize and max_score >= args.threshold: 379 canonical_dir = args.path / 'sessions' / 'canonical' 380 canonical_dir.mkdir(parents=True, exist_ok=True) 381 382 filepath = create_canonical_entry( 383 text, resonances, max_axiom, max_score, canonical_dir 384 ) 385 print(f"✓ Canonical entry created: {filepath}") 386 elif args.canonize: 387 print(f"⚠ Resonance ({max_score:.0%}) below threshold ({args.threshold:.0%})") 388 print(" Not canonized. Use --threshold to adjust.") 389 390 return 0 391 392 393 if __name__ == '__main__': 394 sys.exit(main())