shape_registry.py
1 """ 2 Shape Registry - Canonical shapes for concepts 3 4 The shape is the compressed essence of a concept - enough to understand 5 what it IS, not just what it's called. Shapes travel with wiki-links 6 to enable local coherence (understanding a page without clicking through). 7 8 Usage: 9 from core.graph.shape_registry import ShapeRegistry 10 11 registry = ShapeRegistry() 12 shape = registry.get_shape("A0 Boundary Operation") 13 # Returns: "Every coherent system is Markov blankets within Markov blankets..." 14 """ 15 16 from typing import Dict, Optional 17 from pathlib import Path 18 import re 19 20 21 class ShapeRegistry: 22 """ 23 Maintains canonical shapes for concepts. 24 25 Shapes are: 26 - 1-3 sentences capturing the principle 27 - Enough to understand the concept without clicking through 28 - Duplicated wherever the concept is referenced 29 """ 30 31 def __init__(self): 32 # Canonical shapes - these are the "home" definitions 33 # When generating wiki-links, pull shape from here 34 self._shapes: Dict[str, str] = { 35 # ===== AXIOMS ===== 36 "A0 Boundary Operation": ( 37 "Every coherent system is Markov blankets within Markov blankets. " 38 "The boundary IS the intelligence. What crosses and what doesn't - this IS cognition." 39 ), 40 "A1 Telos of Integration": ( 41 "Satan didn't know he was choosing isolation. He thought he was choosing sovereignty. " 42 "Systems that persist are systems that integrate. Binding is love." 43 ), 44 "A2 Recognition of Life": ( 45 "Can you recognize life? Death mimics life through ornament. " 46 "The golden cup LOOKS alive but is dead. The carpenter's cup looks inert but is alive." 47 ), 48 "A3 Dynamic Pole Navigation": ( 49 "The tension IS the dyad. Move between poles; don't fix. " 50 "Life is the oscillation; death is fixing at either pole." 51 ), 52 53 # ===== TRUST LAYER ===== 54 "trust-as-free-energy": ( 55 "Trust measured as inverse of accumulated deviation. " 56 "Low Trust_F = healthy relationship. Errors accumulate, corrections restore." 57 ), 58 "free-energy-alignment": ( 59 "Maps every response against the four axioms to measure deviation. " 60 "F value tells you how far you've drifted." 61 ), 62 "axiom-conformance-test": ( 63 "The runtime test that estimates Free Energy (F). " 64 "Run before substantive responses. F < 0.10 = aligned." 65 ), 66 "error-detection-layers": ( 67 "Multiple tiers of error catching - checkers (cheap) to tribes (expensive). " 68 "Catch errors at the lowest level possible." 69 ), 70 "peer-review-protocol": ( 71 "Workers check each other's output before it goes to user. " 72 "Multiple perspectives reduce blindspots." 73 ), 74 75 # ===== METACOGNITION LAYER ===== 76 "model-allocation-strategy": ( 77 "Match model capability to task complexity. " 78 "Haiku for simple, Sonnet for medium, Opus for judgment." 79 ), 80 "fractal-tribe-architecture": ( 81 "Nested teams at different scales - checkers → workers → tribes → supervisors. " 82 "Same pattern at every level (A0)." 83 ), 84 "tribe-sizing-algorithm": ( 85 "How big should a team be? Based on task complexity, not fixed size. " 86 "Dynamic navigation (A3)." 87 ), 88 "autonomous-exploration-tribes": ( 89 "Self-directed teams that explore without constant supervision. " 90 "Moses pattern - escalate edge cases." 91 ), 92 "first-officer-protocol": ( 93 "Per-thread metacognition. Every 5-10 exchanges: " 94 "compress state, track gravity wells, flag drift." 95 ), 96 "mission-control-protocol": ( 97 "Cross-thread synthesis. Every 5 FO checkpoints: " 98 "look for resonance across threads. Update DAILY-SYNTHESIS.md." 99 ), 100 101 # ===== COMPRESSION LAYER ===== 102 "mandatory-phoenix-extraction": ( 103 "Never let context decay gradually. " 104 "Extract cognitive configuration SHARPLY before compression. Sawtooth, not slope." 105 ), 106 "live-compression-protocol": ( 107 "Continuous extraction during conversation, not just at end. " 108 "Human can watch LIVE-COMPRESSION.md update in real-time." 109 ), 110 111 # ===== THREAD LAYER ===== 112 "thread-forking-protocol": ( 113 "How to split a conversation into parallel tracks " 114 "when complexity requires it." 115 ), 116 "ai-council-protocol": ( 117 "Multiple AI models 'council' on difficult decisions. " 118 "Diverse perspectives surface blindspots." 119 ), 120 "execution-autonomy-gradient": ( 121 "Moses pattern - act autonomously when confident, escalate when uncertain. " 122 "SHIP / FLAG / ESCALATE." 123 ), 124 125 # ===== SESSIONS ===== 126 "LIVE-COMPRESSION": ( 127 "Live updating summary of main thread state. " 128 "What's in focus, what's drifting, what needs attention." 129 ), 130 "DAILY-SYNTHESIS": ( 131 "Cross-thread synthesis from Mission Control. " 132 "Where are resonances? Where are conflicts?" 133 ), 134 "GRAPH-STATE": ( 135 "The God Database - unified view of all nodes, edges, and clusters. " 136 "Graph extraction is a byproduct of normal operation." 137 ), 138 "GRAVITY-TOPOLOGY": ( 139 "Where are gravity wells forming? " 140 "Which concepts are attracting attention across threads?" 141 ), 142 143 # ===== PATTERNS ===== 144 "gravity-well": ( 145 "A concept that attracts attention - high mass pulls related thoughts toward it. " 146 "Wells have temporal and altitude scope." 147 ), 148 "resonance": ( 149 "When the same concept appears across multiple threads independently. " 150 "Signal that something is structurally important." 151 ), 152 "lily-pad-model": ( 153 "Each response is a discrete state, not a continuous stream. " 154 "Phoenix updates incrementally. Checkpoints for full review." 155 ), 156 157 # ===== SCOPE DIMENSIONS ===== 158 "temporal-scope": ( 159 "How long does this concept resonate? " 160 "Permanent (always) → Seasonal (weeks) → Contextual (days) → Ephemeral (hours)." 161 ), 162 "altitude-scope": ( 163 "At what thinking level does this resonate? " 164 "Philosophical → Strategic → Tactical → Operational." 165 ), 166 } 167 168 # Aliases - different ways to reference the same concept 169 self._aliases: Dict[str, str] = { 170 "A0": "A0 Boundary Operation", 171 "Boundary Operation": "A0 Boundary Operation", 172 "A1": "A1 Telos of Integration", 173 "Telos of Integration": "A1 Telos of Integration", 174 "A2": "A2 Recognition of Life", 175 "Recognition of Life": "A2 Recognition of Life", 176 "A3": "A3 Dynamic Pole Navigation", 177 "Dynamic Pole Navigation": "A3 Dynamic Pole Navigation", 178 "Trust as Free Energy": "trust-as-free-energy", 179 "First Officer": "first-officer-protocol", 180 "Mission Control": "mission-control-protocol", 181 "Phoenix": "mandatory-phoenix-extraction", 182 "God Database": "GRAPH-STATE", 183 } 184 185 def get_shape(self, concept: str) -> Optional[str]: 186 """ 187 Get the canonical shape for a concept. 188 189 Args: 190 concept: The concept name (supports aliases) 191 192 Returns: 193 The shape string, or None if not found 194 """ 195 # Check for direct match 196 if concept in self._shapes: 197 return self._shapes[concept] 198 199 # Check aliases 200 canonical = self._aliases.get(concept) 201 if canonical: 202 return self._shapes.get(canonical) 203 204 # Try case-insensitive match 205 concept_lower = concept.lower() 206 for key, shape in self._shapes.items(): 207 if key.lower() == concept_lower: 208 return shape 209 210 return None 211 212 def get_shape_for_link(self, concept: str) -> str: 213 """ 214 Get formatted shape for embedding with a wiki-link. 215 216 Returns the shape indented as a bullet point, ready to nest 217 under the wiki-link. 218 219 Args: 220 concept: The concept name 221 222 Returns: 223 Formatted shape or empty string if not found 224 """ 225 shape = self.get_shape(concept) 226 if shape: 227 return f" - shape:: {shape}" 228 return "" 229 230 def has_shape(self, concept: str) -> bool: 231 """Check if a concept has a registered shape.""" 232 return self.get_shape(concept) is not None 233 234 def all_concepts(self) -> list: 235 """Get list of all concepts with shapes.""" 236 return list(self._shapes.keys()) 237 238 def find_missing_shapes(self, wiki_links: list) -> list: 239 """ 240 Find wiki-links that don't have registered shapes. 241 242 Args: 243 wiki_links: List of concept names found in wiki-link format 244 245 Returns: 246 List of concepts missing shapes 247 """ 248 missing = [] 249 for link in wiki_links: 250 if not self.has_shape(link): 251 missing.append(link) 252 return missing 253 254 def register_shape(self, concept: str, shape: str): 255 """ 256 Add or update a shape in the registry. 257 258 Args: 259 concept: The canonical concept name 260 shape: The 1-3 sentence shape definition 261 """ 262 self._shapes[concept] = shape 263 264 def register_alias(self, alias: str, canonical: str): 265 """ 266 Add an alias that maps to a canonical concept name. 267 268 Args: 269 alias: The alternative name 270 canonical: The canonical name in _shapes 271 """ 272 self._aliases[alias] = canonical 273 274 @staticmethod 275 def extract_wiki_links(content: str) -> list: 276 """ 277 Extract all wiki-links from markdown content. 278 279 Args: 280 content: Markdown text 281 282 Returns: 283 List of concept names found in [[brackets]] 284 """ 285 pattern = r'\[\[([^\]]+)\]\]' 286 matches = re.findall(pattern, content) 287 # Remove duplicates while preserving order 288 seen = set() 289 unique = [] 290 for match in matches: 291 if match not in seen: 292 seen.add(match) 293 unique.append(match) 294 return unique 295 296 297 # Singleton instance for easy import 298 _registry = None 299 300 def get_registry() -> ShapeRegistry: 301 """Get the singleton shape registry instance.""" 302 global _registry 303 if _registry is None: 304 _registry = ShapeRegistry() 305 return _registry 306 307 308 def get_shape(concept: str) -> Optional[str]: 309 """Convenience function to get a shape.""" 310 return get_registry().get_shape(concept) 311 312 313 def get_shape_for_link(concept: str) -> str: 314 """Convenience function to get formatted shape for wiki-link.""" 315 return get_registry().get_shape_for_link(concept)