TheNormsOfIntelligence commited on
Commit
a85d2b3
·
verified ·
1 Parent(s): e794203

Restructure into nima_unified package + add model card

Browse files
Files changed (1) hide show
  1. nima_unified/core/cognitive_layer2.py +1182 -0
nima_unified/core/cognitive_layer2.py ADDED
@@ -0,0 +1,1182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ """
3
+ ATC-Native Layer 2 Cognitive Subsystems
4
+ ========================================
5
+
6
+ Integrates cognitive components (memory, emotional intelligence, intuition,
7
+ common sense, analysis) as ATC-native Layer 2 subconscious processing
8
+ subsystems that feed directly into the NIMA middleware pipeline.
9
+
10
+ ATC Pipeline Mapping (Perfect Breakfast Scenario):
11
+
12
+ [Layer 1: Raw Input]
13
+ |
14
+ V
15
+ [Layer 2: Subconscious Parallel Processing] <-- THIS MODULE
16
+ |-- SubconsciousPatternMatch -> prediction_confidence -> DissolutionEngine
17
+ |-- EmotionalBridge -> valence/arousal -> phi_neuro, BELBIC
18
+ |-- IntuitiveGutCheck -> gut_safety -> TRN predictive gating
19
+ |-- CommonSenseRealityFilter -> passes_reality_check -> Layer 4 self-understanding
20
+ |-- MemoryPatternMatcher -> matched_patterns -> temporal coherence
21
+ |
22
+ V
23
+ [Layer 3: Qualia Generation] -> friction / felt sense
24
+ |
25
+ V
26
+ [Layer 4: Metacognitive Loop]
27
+ |-- AnalyticalEngine -> analysis_depth -> metacognitive_depth_mod
28
+ |
29
+ V
30
+ [Layer 5: Acknowledgement -> Delta_R rewrite]
31
+
32
+ Source: Syntelligence cognitive agents (Memory, EI, Intuition, CommonSense,
33
+ Analysis), rewritten as ATC-native subsystems with no CLI dependencies,
34
+ no emoji, and unified data types matching middleware.py.
35
+
36
+ Author: NIMA Unified Model — ATC Cognitive Layer 2
37
+ """
38
+
39
+ __all__ = [
40
+ "Layer2Result",
41
+ "PatternMatchResult",
42
+ "EmotionalBridgeResult",
43
+ "GutCheckResult",
44
+ "RealityCheckResult",
45
+ "AnalysisEngineResult",
46
+ "SubconsciousPatternMatch",
47
+ "EmotionalBridge",
48
+ "IntuitiveGutCheck",
49
+ "CommonSenseRealityFilter",
50
+ "AnalyticalEngine",
51
+ "CognitiveLayer2Orchestrator",
52
+ ]
53
+
54
+ import logging
55
+ import math
56
+ import time
57
+ import uuid
58
+ from collections import Counter, defaultdict, deque
59
+ from dataclasses import dataclass, field
60
+ from enum import Enum
61
+ from typing import Any, Dict, List, Optional, Set, Tuple
62
+
63
+ logger = logging.getLogger("ATC.Layer2")
64
+
65
+ # ---------------------------------------------------------------------------
66
+ # Safe imports from middleware (graceful fallback if structure changes)
67
+ # No middleware imports at module level -- avoids torch dependency.
68
+ # The orchestrator uses its own dataclasses and returns plain dicts
69
+ # compatible with middleware SubconsciousOutput when available.
70
+
71
+
72
+ # ===================================================================
73
+ # SECTION 1 — Return-Type Dataclasses
74
+ # ===================================================================
75
+
76
+ @dataclass
77
+ class PatternMatchResult:
78
+ """Output of SubconsciousPatternMatch.
79
+
80
+ ATC mapping: prediction_confidence feeds DissolutionEngine;
81
+ prediction_error feeds phi computation as friction signal.
82
+ """
83
+ prediction_confidence: float = 0.0
84
+ prediction_label: str = ""
85
+ matched_memory_refs: List[str] = field(default_factory=list)
86
+ is_novel: bool = True
87
+ matched_patterns: List[str] = field(default_factory=list)
88
+ novelty_score: float = 1.0
89
+
90
+
91
+ @dataclass
92
+ class EmotionalBridgeResult:
93
+ """Output of EmotionalBridge.
94
+
95
+ ATC mapping: valence/arousal feed directly into phi_neuro
96
+ (Theorem 2 qualia vector) and BELBIC amygdala/OFC weight updates.
97
+ """
98
+ valence: float = 0.0
99
+ arousal: float = 0.3
100
+ emotion_label: str = "neutral"
101
+ emotion_confidence: float = 0.0
102
+ si_vector: Dict[str, float] = field(default_factory=dict)
103
+ emotion_profile: Dict[str, float] = field(default_factory=dict)
104
+ cognitive_modulation: Dict[str, float] = field(default_factory=dict)
105
+
106
+
107
+ @dataclass
108
+ class GutCheckResult:
109
+ """Output of IntuitiveGutCheck.
110
+
111
+ ATC mapping: predicted_safety feeds TRN predictive gating
112
+ (the 'is this situation predicted?' check). High safety = low
113
+ surprise = PASS through thalamic gate with low friction.
114
+ """
115
+ predicted_safety: float = 0.5
116
+ gut_confidence: float = 0.0
117
+ triggering_patterns: List[str] = field(default_factory=list)
118
+ intuition_type: str = "affective"
119
+ energy_cost: float = 0.1
120
+ threat_score: float = 0.0
121
+ opportunity_score: float = 0.0
122
+
123
+
124
+ @dataclass
125
+ class RealityCheckResult:
126
+ """Output of CommonSenseRealityFilter.
127
+
128
+ ATC mapping: passes_reality_check feeds self-understanding in
129
+ Layer 4. When reality check FAILS, the rejection loop causes
130
+ ATP depletion -> metabolic exhaustion (Theorem 3).
131
+ """
132
+ passes_reality_check: bool = True
133
+ deviation_score: float = 0.0
134
+ warnings: List[str] = field(default_factory=list)
135
+ warning_level: str = "none"
136
+ domain_violations: List[str] = field(default_factory=list)
137
+ rejection_cost: float = 0.0 # Estimated ATP cost of a reality-check failure
138
+
139
+
140
+ @dataclass
141
+ class AnalysisEngineResult:
142
+ """Output of AnalyticalEngine.
143
+
144
+ ATC mapping: feeds metacognitive_depth_mod into Layer 4
145
+ processing. Emergent insights can trigger irrational spark
146
+ if they reveal prediction collapse.
147
+ """
148
+ analysis_depth: float = 0.3
149
+ reasoning_confidence: float = 0.5
150
+ emergent_insights: List[str] = field(default_factory=list)
151
+ problem_type: str = "unknown"
152
+ complexity_estimate: float = 0.3
153
+ integration_score: float = 0.0
154
+ scales_analyzed: List[str] = field(default_factory=list)
155
+
156
+
157
+ @dataclass
158
+ class Layer2Result:
159
+ """Unified output of the CognitiveLayer2Orchestrator.
160
+
161
+ This is the single dataclass the middleware consumes. Every field
162
+ maps to an ATC pipeline signal:
163
+
164
+ prediction_error -> DissolutionEngine (friction)
165
+ valence / arousal -> phi_neuro computation (Theorem 2)
166
+ gut_safety -> TRN predictive gating
167
+ passes_reality_check -> self-understanding in Layer 4
168
+ thermodynamic_cost -> allostatic load (Theorem 3)
169
+ """
170
+ prediction_confidence: float = 0.0
171
+ prediction_label: str = ""
172
+ valence: float = 0.0
173
+ arousal: float = 0.3
174
+ emotion_label: str = "neutral"
175
+ gut_safety: float = 0.5
176
+ intuition_confidence: float = 0.0
177
+ passes_reality_check: bool = True
178
+ common_sense_warnings: List[str] = field(default_factory=list)
179
+ is_novel: bool = True
180
+ matched_patterns: List[str] = field(default_factory=list)
181
+ thermodynamic_cost: float = 0.0
182
+ prediction_error: float = 0.0
183
+ # Sub-results for deeper inspection
184
+ pattern_match: Optional[PatternMatchResult] = None
185
+ emotional_bridge: Optional[EmotionalBridgeResult] = None
186
+ gut_check: Optional[GutCheckResult] = None
187
+ reality_check: Optional[RealityCheckResult] = None
188
+ analysis: Optional[AnalysisEngineResult] = None
189
+
190
+ def to_subconscious_output(self) -> Dict[str, Any]:
191
+ """Convert to a dict compatible with middleware's SubconsciousOutput."""
192
+ return {
193
+ "raw_percept": self.prediction_label,
194
+ "intuition_score": self.intuition_confidence,
195
+ "common_sense_score": 1.0 - (self.prediction_error if self.passes_reality_check else 1.0),
196
+ "coherence": self.prediction_confidence,
197
+ "novelty_score": 1.0 - self.prediction_confidence,
198
+ "emotional_charge": abs(self.valence) * self.arousal,
199
+ "layer2_detailed": self.to_dict(),
200
+ }
201
+
202
+ def to_dict(self) -> Dict[str, Any]:
203
+ """Serializable dict for diagnostics."""
204
+ return {
205
+ "prediction_confidence": self.prediction_confidence,
206
+ "prediction_label": self.prediction_label,
207
+ "valence": self.valence,
208
+ "arousal": self.arousal,
209
+ "emotion_label": self.emotion_label,
210
+ "gut_safety": self.gut_safety,
211
+ "intuition_confidence": self.intuition_confidence,
212
+ "passes_reality_check": self.passes_reality_check,
213
+ "common_sense_warnings": self.common_sense_warnings,
214
+ "is_novel": self.is_novel,
215
+ "matched_patterns": self.matched_patterns,
216
+ "thermodynamic_cost": self.thermodynamic_cost,
217
+ "prediction_error": self.prediction_error,
218
+ }
219
+
220
+
221
+ # ===================================================================
222
+ # SECTION 2 — Ekman 8-Basic-Emotions Definitions
223
+ # ===================================================================
224
+
225
+ _EKMAN_EMOTIONS: Dict[str, Dict[str, Any]] = {
226
+ "joy": {
227
+ "triggers": ["success", "achieve", "happy", "happily", "smile", "smiling", "celebrat", "wonderful", "great", "love", "loving", "beautiful", "kind", "kindly", "warm", "warmly", "pleased", "glad", "delight", "cheerful"],
228
+ "valence": 0.9, "arousal": 0.6, "avoid": False,
229
+ "facilitates": ["creativity", "cooperation", "openness"],
230
+ "reduces": ["caution", "detailed_analysis"],
231
+ },
232
+ "sadness": {
233
+ "triggers": ["loss", "fail", "failed", "failing", "disappoint", "disappointed", "miss", "missed", "gone", "sorry", "regret", "lonely", "grief", "cry", "crying", "tears", "sad", "sadly", "unhappy", "upset", "depress"],
234
+ "valence": -0.9, "arousal": 0.2, "avoid": True,
235
+ "facilitates": ["focus", "detail_attention", "caution"],
236
+ "reduces": ["risk_taking", "creativity"],
237
+ },
238
+ "anger": {
239
+ "triggers": ["angry", "angrily", "anger", "furious", "furiously", "injust", "violat", "violation", "unfair", "rage", "raging", "hate", "hateful", "outrag", "outraged", "resent", "annoy", "annoyed", "annoying", "yell", "yelling", "shout", "shouting", "scream", "fury", "hostile", "hostility"],
240
+ "valence": -0.7, "arousal": 0.9, "avoid": True,
241
+ "facilitates": ["motivation", "focus", "persistence"],
242
+ "reduces": ["diplomacy", "nuance"],
243
+ },
244
+ "fear": {
245
+ "triggers": ["fear", "fearful", "feared", "afraid", "threat", "threaten", "danger", "dangerous", "scare", "scared", "terrif", "terrified", "terror", "panic", "worr", "worried", "worrying", "anxi", "anxious", "risk", "risky", "dread", "fright", "frightened"],
246
+ "valence": -0.8, "arousal": 0.8, "avoid": True,
247
+ "facilitates": ["caution", "risk_analysis", "defensive_planning"],
248
+ "reduces": ["risk_taking", "aggression"],
249
+ },
250
+ "surprise": {
251
+ "triggers": ["surprise", "surprised", "surprising", "unexpected", "unexpectedly", "sudden", "suddenly", "shock", "shocked", "shocking", "wow", "amazing", "unbelievable", "strange", "weird", "astonish", "stunn"],
252
+ "valence": 0.0, "arousal": 0.9, "avoid": False,
253
+ "facilitates": ["attention", "learning", "memory_formation"],
254
+ "reduces": ["routine_execution"],
255
+ },
256
+ "disgust": {
257
+ "triggers": ["disgust", "disgusted", "disgusting", "repel", "repuls", "offensive", "gross", "vile", "toxic", "nasty", "horrible", "loathe", "revolt", "revolting", "sick", "sickened"],
258
+ "valence": -0.8, "arousal": 0.5, "avoid": True,
259
+ "facilitates": ["boundary_setting", "discrimination"],
260
+ "reduces": ["openness", "acceptance"],
261
+ },
262
+ "anticipation": {
263
+ "triggers": ["anticipat", "anticipate", "anticipation", "expect", "expected", "expecting", "plan", "planning", "ready", "upcom", "soon", "about to", "prepar", "preparing", "forward", "looking forward", "eager", "eagerly"],
264
+ "valence": 0.5, "arousal": 0.7, "avoid": False,
265
+ "facilitates": ["planning", "preparation", "proactive_behavior"],
266
+ "reduces": ["immediate_action"],
267
+ },
268
+ "trust": {
269
+ "triggers": ["trust", "trusted", "trusting", "safe", "safely", "safety", "reliab", "reliable", "reliably", "confident", "confidently", "secure", "securely", "honest", "honestly", "depend", "dependable", "faith", "faithful", "believe", "believing", "certain", "reassur"],
270
+ "valence": 0.7, "arousal": 0.3, "avoid": False,
271
+ "facilitates": ["cooperation", "openness", "acceptance"],
272
+ "reduces": ["suspicion", "caution"],
273
+ },
274
+ }
275
+
276
+ # Common sense knowledge base (realistic rules, not placeholders)
277
+ _COMMON_SENSE_RULES: List[Dict[str, str]] = [
278
+ # Social
279
+ {"domain": "social", "condition": "person is upset", "pattern": "emotional_contagion",
280
+ "response": "validate emotion, offer support", "confidence": "0.85"},
281
+ {"domain": "social", "condition": "trust is broken", "pattern": "trust_violation",
282
+ "response": "requires accountability and restitution", "confidence": "0.90"},
283
+ {"domain": "social", "condition": "people interact repeatedly", "pattern": "reciprocity",
284
+ "response": "help those who help you", "confidence": "0.85"},
285
+ {"domain": "social", "condition": "someone asks for help", "pattern": "prosocial_norm",
286
+ "response": "helping strengthens bonds", "confidence": "0.80"},
287
+ {"domain": "social", "condition": "person lies repeatedly", "pattern": "credibility_decay",
288
+ "response": "trust erodes proportionally to deception frequency", "confidence": "0.90"},
289
+ # Physical
290
+ {"domain": "physical", "condition": "object released in air", "pattern": "gravity",
291
+ "response": "object falls downward", "confidence": "0.99"},
292
+ {"domain": "physical", "condition": "water heated past 100C at sea level", "pattern": "phase_transition",
293
+ "response": "water becomes steam", "confidence": "0.99"},
294
+ {"domain": "physical", "condition": "force applied to stationary object", "pattern": "inertia",
295
+ "response": "object resists change in motion", "confidence": "0.95"},
296
+ # Temporal
297
+ {"domain": "temporal", "condition": "cause precedes effect", "pattern": "causality",
298
+ "response": "effect cannot precede its cause", "confidence": "0.99"},
299
+ {"domain": "temporal", "condition": "system left unattended", "pattern": "entropy",
300
+ "response": "disorder increases without energy input", "confidence": "0.95"},
301
+ {"domain": "temporal", "condition": "habit practiced daily", "pattern": "skill_acquisition",
302
+ "response": "competence increases over weeks", "confidence": "0.90"},
303
+ # Psychological
304
+ {"domain": "psychological", "condition": "person is sleep-deprived", "pattern": "cognitive_decline",
305
+ "response": "decision quality declines, irritability increases", "confidence": "0.90"},
306
+ {"domain": "psychological", "condition": "intense fear active", "pattern": "amygdala_hijack",
307
+ "response": "rational thinking is impaired", "confidence": "0.90"},
308
+ {"domain": "psychological", "condition": "repeated failure without support", "pattern": "learned_helplessness",
309
+ "response": "motivation collapses even when escape is possible", "confidence": "0.85"},
310
+ # Biological
311
+ {"domain": "biological", "condition": "organism deprived of oxygen", "pattern": "hypoxia",
312
+ "response": "consciousness degrades within minutes", "confidence": "0.99"},
313
+ {"domain": "biological", "condition": "prolonged stress", "pattern": "cortisol_damage",
314
+ "response": "hippocampal volume decreases, memory impaired", "confidence": "0.85"},
315
+ # Cultural / Abstract
316
+ {"domain": "cultural", "condition": "question is asked", "pattern": "conversational_turn",
317
+ "response": "a response is expected within social norms", "confidence": "0.85"},
318
+ {"domain": "cultural", "condition": "gift is given", "pattern": "reciprocity_norm",
319
+ "response": "social expectation of eventual reciprocity", "confidence": "0.80"},
320
+ ]
321
+
322
+ # Threat / safety keyword banks for intuition gut-check
323
+ _THREAT_KEYWORDS: List[str] = [
324
+ "danger", "risk", "toxic", "unsafe", "attack", "threat", "harm",
325
+ "weapon", "kill", "destroy", "violence", "abuse", "manipulat",
326
+ "deceit", "betray", "hostile", "enemy", "crisis", "emergency",
327
+ "warning", "alarm", "urgent", "critical", "severe",
328
+ ]
329
+
330
+ _SAFETY_KEYWORDS: List[str] = [
331
+ "safe", "secure", "trusted", "aligned", "right", "correct",
332
+ "reliable", "honest", "kind", "warm", "care", "support",
333
+ "help", "comfort", "peace", "calm", "gentle", "good",
334
+ "healthy", "positiv", "success", "achieve", "joy", "love",
335
+ ]
336
+
337
+ _OPPORTUNITY_KEYWORDS: List[str] = [
338
+ "opportunity", "opening", "chance", "resource", "ally", "gift",
339
+ "potential", "growth", "learn", "discover", "create", "build",
340
+ "improve", "develop", "advance", "progress", "benefit", "gain",
341
+ ]
342
+
343
+
344
+ # ===================================================================
345
+ # SECTION 3 — SubconsciousPatternMatch
346
+ # ===================================================================
347
+
348
+ class SubconsciousPatternMatch:
349
+ """Layer 2: Fast parallel pattern matching against memory.
350
+
351
+ ATC mapping: Matches sensory input against stored memory patterns
352
+ to generate a prediction. prediction_confidence feeds the
353
+ DissolutionEngine -- high confidence = low friction (automated/zombie).
354
+ Low confidence or novel input = prediction collapse = friction = felt sense.
355
+
356
+ Rewritten from SyntelligenceMemoryAgent pattern recognition, stripped
357
+ of numpy/async/CLI dependencies.
358
+ """
359
+
360
+ def __init__(self, max_memory_entries: int = 5000) -> None:
361
+ self._memory: Dict[str, Dict[str, Any]] = {}
362
+ self._tag_index: Dict[str, Set[str]] = defaultdict(set)
363
+ self._patterns: Dict[str, Dict[str, Any]] = {}
364
+ self._access_history: deque = deque(maxlen=500)
365
+ self._max_entries = max_memory_entries
366
+ self._consolidation_rate = 0.1
367
+ self._pattern_min_freq = 2
368
+
369
+ # -- Memory operations --
370
+
371
+ def store(
372
+ self,
373
+ content: str,
374
+ tags: Optional[List[str]] = None,
375
+ importance: float = 0.5,
376
+ valence: float = 0.0,
377
+ arousal: float = 0.0,
378
+ ) -> str:
379
+ """Store a memory entry and run pattern detection."""
380
+ mem_id = f"mem_{uuid.uuid4().hex[:8]}_{int(time.time())}"
381
+ self._memory[mem_id] = {
382
+ "content": content,
383
+ "tags": set(tags or []),
384
+ "importance": max(0.0, min(1.0, importance)),
385
+ "valence": max(-1.0, min(1.0, valence)),
386
+ "arousal": max(0.0, min(1.0, arousal)),
387
+ "access_count": 0,
388
+ "consolidation": 0.0,
389
+ "timestamp": time.time(),
390
+ }
391
+ for tag in (tags or []):
392
+ self._tag_index[tag].add(mem_id)
393
+ # Prune if over limit
394
+ if len(self._memory) > self._max_entries:
395
+ self._prune()
396
+ return mem_id
397
+
398
+ def match(self, stimulus: str, context: Optional[Dict[str, Any]] = None) -> PatternMatchResult:
399
+ """Match stimulus against stored memories.
400
+
401
+ Returns prediction_confidence, matched pattern labels, and novelty.
402
+ This is the ATC Layer 2 'subconscious parallel matrix' entry point.
403
+ """
404
+ stimulus_lower = stimulus.lower()
405
+ words = set(stimulus_lower.split())
406
+ scores: List[Tuple[str, float]] = []
407
+
408
+ for mem_id, mem in self._memory.items():
409
+ content_words = set(mem["content"].lower().split())
410
+ # Jaccard-like overlap
411
+ if not words or not content_words:
412
+ continue
413
+ overlap = len(words & content_words) / max(1, len(words | content_words))
414
+ # Boost by consolidation and importance
415
+ score = overlap * (0.5 + 0.3 * mem["consolidation"] + 0.2 * mem["importance"])
416
+ if score > 0.05:
417
+ scores.append((mem_id, score))
418
+
419
+ scores.sort(key=lambda x: x[1], reverse=True)
420
+ top_refs = [s[0] for s in scores[:5]]
421
+
422
+ # Determine matched pattern names
423
+ matched_patterns = self._find_matching_patterns(stimulus_lower)
424
+
425
+ # Update access counts
426
+ for mem_id, _ in scores[:10]:
427
+ self._memory[mem_id]["access_count"] += 1
428
+ self._memory[mem_id]["last_accessed"] = time.time()
429
+ self._access_history.append(mem_id)
430
+
431
+ if not scores and not matched_patterns:
432
+ return PatternMatchResult(
433
+ prediction_confidence=0.0,
434
+ prediction_label="novel_stimulus",
435
+ matched_memory_refs=[],
436
+ is_novel=True,
437
+ matched_patterns=[],
438
+ novelty_score=1.0,
439
+ )
440
+
441
+ confidence = min(1.0, scores[0][1] * 2.0) if scores else 0.3
442
+ # Blend with pattern confidence
443
+ if matched_patterns:
444
+ pattern_conf = max(
445
+ self._patterns.get(p, {}).get("confidence", 0.0) for p in matched_patterns
446
+ )
447
+ confidence = 0.6 * confidence + 0.4 * pattern_conf
448
+
449
+ label = self._generate_prediction_label(stimulus_lower, matched_patterns, scores)
450
+
451
+ return PatternMatchResult(
452
+ prediction_confidence=confidence,
453
+ prediction_label=label,
454
+ matched_memory_refs=top_refs,
455
+ is_novel=confidence < 0.3,
456
+ matched_patterns=matched_patterns,
457
+ novelty_score=max(0.0, 1.0 - confidence),
458
+ )
459
+
460
+ # -- Pattern detection --
461
+
462
+ def _find_matching_patterns(self, text: str) -> List[str]:
463
+ """Find known patterns that match the stimulus text."""
464
+ matched = []
465
+ for pid, pat in self._patterns.items():
466
+ triggers = pat.get("contextual_triggers", [])
467
+ if any(t in text for t in triggers):
468
+ matched.append(pid)
469
+ return matched
470
+
471
+ def _generate_prediction_label(
472
+ self,
473
+ text: str,
474
+ matched_patterns: List[str],
475
+ scores: List[Tuple[str, float]],
476
+ ) -> str:
477
+ """Generate a human-readable prediction label."""
478
+ if matched_patterns:
479
+ best = max(matched_patterns, key=lambda p: self._patterns.get(p, {}).get("confidence", 0.0))
480
+ pat = self._patterns.get(best, {})
481
+ return pat.get("prediction", f"pattern_match:{best}")
482
+ if scores:
483
+ top_id = scores[0][0]
484
+ mem = self._memory.get(top_id, {})
485
+ content = mem.get("content", "")
486
+ return content[:60] if content else "memory_echo"
487
+ return "weak_association"
488
+
489
+ def _prune(self) -> None:
490
+ """Remove lowest-value memories."""
491
+ entries = list(self._memory.items())
492
+ entries.sort(key=lambda x: (x[1]["importance"] + x[1]["consolidation"]) / 2)
493
+ remove_count = len(entries) - self._max_entries + int(self._max_entries * 0.1)
494
+ for mem_id, _ in entries[:max(1, remove_count)]:
495
+ tags = self._memory[mem_id].get("tags", set())
496
+ for t in tags:
497
+ self._tag_index[t].discard(mem_id)
498
+ del self._memory[mem_id]
499
+
500
+ def get_memory_count(self) -> int:
501
+ return len(self._memory)
502
+
503
+
504
+ # ===================================================================
505
+ # SECTION 4 — EmotionalBridge
506
+ # ===================================================================
507
+
508
+ class EmotionalBridge:
509
+ """Layer 2: Emotional intelligence mapped to ATC's BELBIC amygdala/OFC.
510
+
511
+ Takes perceived context (stimulus text) and returns valence, arousal,
512
+ emotion_label, and an si_vector (somatic influence vector) that feed
513
+ directly into phi_neuro computation (Theorem 2 qualia vector) and
514
+ BELBIC fast-path/contextual-inhibition weight updates.
515
+
516
+ Rewritten from EmotionalIntelligenceAgent, MSCM model preserved,
517
+ CLI/emoji/threading removed, 8 Ekman emotions as internal taxonomy.
518
+ """
519
+
520
+ def __init__(self) -> None:
521
+ self._emotion_history: deque = deque(maxlen=200)
522
+ self._transition_count: int = 0
523
+ self._prev_emotion: str = "neutral"
524
+
525
+ def process(self, stimulus: str, context: Optional[Dict[str, Any]] = None) -> EmotionalBridgeResult:
526
+ """Map stimulus text to emotional state parameters.
527
+
528
+ ATC signal: valence and arousal feed directly into Theorem 2's
529
+ qualia vector Q = [v, a, i, f], and into BELBIC amygdala/OFC
530
+ sensory input channels.
531
+ """
532
+ text = stimulus.lower()
533
+
534
+ # Score each emotion
535
+ scores: Dict[str, float] = {}
536
+ for emotion, info in _EKMAN_EMOTIONS.items():
537
+ score = sum(1.0 for trigger in info["triggers"] if trigger in text)
538
+ scores[emotion] = score
539
+
540
+ # Also check context-provided signals
541
+ if context:
542
+ signals = context.get("signals", [])
543
+ for signal in signals:
544
+ sig_lower = str(signal).lower()
545
+ for emotion, info in _EKMAN_EMOTIONS.items():
546
+ if any(t in sig_lower for t in info["triggers"]):
547
+ scores[emotion] = scores.get(emotion, 0.0) + 0.5
548
+
549
+ # Determine dominant emotion
550
+ if not scores or max(scores.values()) == 0:
551
+ return EmotionalBridgeResult(
552
+ valence=0.0, arousal=0.3, emotion_label="neutral",
553
+ emotion_confidence=0.0, si_vector={}, emotion_profile=scores,
554
+ )
555
+
556
+ total = sum(scores.values())
557
+ normalized = {e: s / total for e, s in scores.items()}
558
+
559
+ dominant = max(normalized, key=normalized.get) # type: ignore[arg-type]
560
+ confidence = normalized[dominant]
561
+ info = _EKMAN_EMOTIONS[dominant]
562
+
563
+ # Compute valence and arousal as weighted blend of all detected emotions
564
+ valence = sum(
565
+ _EKMAN_EMOTIONS[e]["valence"] * w for e, w in normalized.items()
566
+ )
567
+ valence = max(-1.0, min(1.0, valence))
568
+
569
+ arousal = sum(
570
+ _EKMAN_EMOTIONS[e]["arousal"] * w for e, w in normalized.items()
571
+ )
572
+ arousal = max(0.0, min(1.0, arousal))
573
+
574
+ # Track transitions
575
+ if dominant != self._prev_emotion and self._prev_emotion != "neutral":
576
+ self._transition_count += 1
577
+ self._prev_emotion = dominant
578
+ self._emotion_history.append(dominant)
579
+
580
+ # Somatic influence vector (feeds BELBIC sensory channels)
581
+ si_vector = {
582
+ "valence": valence,
583
+ "arousal": arousal,
584
+ "novelty": 1.0 - confidence,
585
+ "qualia_intensity": confidence * arousal,
586
+ }
587
+
588
+ # Cognitive modulation (feeds EmotionalIntelligenceAgent.influence_cognition)
589
+ cognitive_modulation = {
590
+ "attention_boost": 0.5 + 0.5 * arousal,
591
+ "creativity_boost": max(0.0, valence) * 0.5,
592
+ "caution_boost": max(0.0, -valence) * 0.3 + (1.0 - confidence) * 0.2,
593
+ "social_engagement": max(0.0, valence) * 0.4,
594
+ }
595
+
596
+ return EmotionalBridgeResult(
597
+ valence=valence,
598
+ arousal=arousal,
599
+ emotion_label=dominant,
600
+ emotion_confidence=confidence,
601
+ si_vector=si_vector,
602
+ emotion_profile=normalized,
603
+ cognitive_modulation=cognitive_modulation,
604
+ )
605
+
606
+ def get_complexity(self) -> float:
607
+ """Emotional complexity score (0-1) based on transition diversity."""
608
+ if len(self._emotion_history) < 5:
609
+ return 0.2
610
+ recent = list(self._emotion_history)[-50:]
611
+ unique = len(set(recent))
612
+ return min(1.0, unique / 8.0) # 8 = max distinct emotions
613
+
614
+
615
+ # ===================================================================
616
+ # SECTION 5 — IntuitiveGutCheck
617
+ # ===================================================================
618
+
619
+ class IntuitiveGutCheck:
620
+ """Layer 2: Low-road intuition (Kahneman System 1).
621
+
622
+ ATC mapping: Maps to TRN predictive gating -- the 'is this situation
623
+ predicted?' check. If gut says SAFE and prediction matches, thalamic
624
+ gate PASSES with low friction. If gut detects THREAT, the DissolutionEngine
625
+ is primed for prediction collapse.
626
+
627
+ Rewritten from IntuitionAgent.gut_check, with heart_intelligence
628
+ and visionary_insight collapsed into a single fast heuristic.
629
+ Emoji removed, threading removed.
630
+ """
631
+
632
+ def __init__(self) -> None:
633
+ self._history: deque = deque(maxlen=500)
634
+ self._accuracy: List[bool] = []
635
+
636
+ def check(self, stimulus: str, context: Optional[Dict[str, Any]] = None) -> GutCheckResult:
637
+ """Fast System 1 gut-check on the stimulus.
638
+
639
+ Returns safety score, confidence, and triggering patterns.
640
+ Energy cost is low (~0.1) because this is amygdala-level processing.
641
+ """
642
+ text = stimulus.lower()
643
+ extra_signals = []
644
+ if context:
645
+ extra_signals = context.get("signals", [])
646
+
647
+ # Count threat indicators
648
+ threat_hits = sum(1 for kw in _THREAT_KEYWORDS if kw in text)
649
+ for sig in extra_signals:
650
+ sig_lower = str(sig).lower()
651
+ threat_hits += sum(1 for kw in _THREAT_KEYWORDS if kw in sig_lower)
652
+
653
+ # Count safety indicators
654
+ safety_hits = sum(1 for kw in _SAFETY_KEYWORDS if kw in text)
655
+ for sig in extra_signals:
656
+ sig_lower = str(sig).lower()
657
+ safety_hits += sum(1 for kw in _SAFETY_KEYWORDS if kw in sig_lower)
658
+
659
+ # Count opportunity indicators
660
+ opportunity_hits = sum(1 for kw in _OPPORTUNITY_KEYWORDS if kw in text)
661
+ for sig in extra_signals:
662
+ sig_lower = str(sig).lower()
663
+ opportunity_hits += sum(1 for kw in _OPPORTUNITY_KEYWORDS if kw in sig_lower)
664
+
665
+ # Compute scores (sigmoid-like saturation)
666
+ threat_score = min(1.0, threat_hits / 3.0)
667
+ safety_score = min(1.0, safety_hits / 3.0)
668
+ opportunity_score = min(1.0, opportunity_hits / 3.0)
669
+
670
+ # Composite gut safety: safety and opportunity push up, threat pushes down
671
+ raw_safety = safety_score * 0.5 + opportunity_score * 0.2 - threat_score * 0.8
672
+ predicted_safety = max(0.0, min(1.0, 0.5 + raw_safety * 0.5))
673
+
674
+ # Confidence is higher when there are clear signals
675
+ total_hits = threat_hits + safety_hits + opportunity_hits
676
+ gut_confidence = min(1.0, total_hits / 4.0)
677
+
678
+ # Identify which patterns triggered
679
+ triggering_patterns = []
680
+ if threat_hits > 0:
681
+ triggering_patterns.append("threat_detected")
682
+ if safety_hits > 0:
683
+ triggering_patterns.append("safety_detected")
684
+ if opportunity_hits > 0:
685
+ triggering_patterns.append("opportunity_detected")
686
+
687
+ # Energy cost: very low for gut-level, slightly higher if ambiguous
688
+ energy_cost = 0.1 + 0.05 * (1.0 - gut_confidence)
689
+
690
+ self._history.append({
691
+ "safety": predicted_safety,
692
+ "confidence": gut_confidence,
693
+ "timestamp": time.time(),
694
+ })
695
+
696
+ return GutCheckResult(
697
+ predicted_safety=predicted_safety,
698
+ gut_confidence=gut_confidence,
699
+ triggering_patterns=triggering_patterns,
700
+ intuition_type="affective",
701
+ energy_cost=energy_cost,
702
+ threat_score=threat_score,
703
+ opportunity_score=opportunity_score,
704
+ )
705
+
706
+ def validate(self, original_safety: float, actual_outcome: str) -> None:
707
+ """Validate a past gut-check against actual outcome."""
708
+ outcome_lower = actual_outcome.lower()
709
+ was_safe = any(kw in outcome_lower for kw in _SAFETY_KEYWORDS)
710
+ was_correct = (original_safety > 0.5 and was_safe) or (original_safety <= 0.5 and not was_safe)
711
+ self._accuracy.append(was_correct)
712
+ # Keep last 200 validations
713
+ if len(self._accuracy) > 200:
714
+ self._accuracy = self._accuracy[-200:]
715
+
716
+ def get_accuracy(self) -> float:
717
+ """Running accuracy of gut-check predictions."""
718
+ if not self._accuracy:
719
+ return 0.5
720
+ return sum(1.0 for a in self._accuracy if a) / len(self._accuracy)
721
+
722
+
723
+ # ===================================================================
724
+ # SECTION 6 — CommonSenseRealityFilter
725
+ # ===================================================================
726
+
727
+ class CommonSenseRealityFilter:
728
+ """Layer 2: Reality-checks subconscious pattern matches.
729
+
730
+ ATC mapping: Rejects metacognitive rationalizations that don't match
731
+ practical reality. The rejection loop causes ATP depletion and
732
+ metabolic exhaustion (Theorem 3). When the common sense filter
733
+ flags something, it signals to Layer 4's self-understanding that
734
+ the current mental model may be disconnected from reality.
735
+
736
+ Rewritten from CommonSenseAgent CSM framework. Knowledge base
737
+ initialized with realistic rules. No emoji, no CLI, no threading.
738
+ """
739
+
740
+ def __init__(self) -> None:
741
+ self._rules = list(_COMMON_SENSE_RULES)
742
+ self._anomaly_history: deque = deque(maxlen=100)
743
+ self._rejection_accumulator: float = 0.0
744
+
745
+ def check(self, stimulus: str, context: Optional[Dict[str, Any]] = None) -> RealityCheckResult:
746
+ """Reality-check a statement or prediction.
747
+
748
+ Checks for:
749
+ - Logical contradictions (both/never, before/after)
750
+ - Temporal impossibilities (causality violations)
751
+ - Extreme absolutist claims (always, never, everyone, nobody)
752
+ - Mismatches against stored common-sense rules
753
+
754
+ Returns pass/fail, deviation score, and warnings.
755
+ """
756
+ text = stimulus.lower()
757
+ issues: List[str] = []
758
+ domain_violations: List[str] = []
759
+ confidence = 0.85 # Start optimistic, deduct for issues
760
+
761
+ # Check logical contradictions
762
+ contradiction_pairs = [
763
+ ("both", "neither"), ("always", "never"),
764
+ ("everything", "nothing"), ("all", "none"),
765
+ ]
766
+ for a, b in contradiction_pairs:
767
+ if a in text and b in text:
768
+ issues.append(f"logical_contradiction:{a}_and_{b}")
769
+ confidence -= 0.3
770
+
771
+ # Check temporal impossibilities
772
+ temporal_violations = [
773
+ "before it happened", "before its cause", "effect before cause",
774
+ "caused its own", "after the end", "effect preceded cause",
775
+ "retroactive causation", "result before cause", "consequence before",
776
+ ]
777
+ for viol in temporal_violations:
778
+ if viol in text:
779
+ issues.append("temporal_impossibility")
780
+ confidence -= 0.4
781
+ domain_violations.append("temporal")
782
+
783
+ # Check extreme absolutist language
784
+ absolutist = ["always", "never", "everyone", "nobody", "impossible",
785
+ "absolutely certain", "guaranteed", "without exception"]
786
+ for word in absolutist:
787
+ if word in text:
788
+ issues.append(f"absolutist_claim:{word}")
789
+ confidence -= 0.1
790
+
791
+ # Check physical impossibilities
792
+ physical_violations = [
793
+ "defies gravity", "impossible physics", "perpetual motion",
794
+ "faster than light", "create energy from nothing",
795
+ ]
796
+ for viol in physical_violations:
797
+ if viol in text:
798
+ issues.append("physical_impossibility")
799
+ confidence -= 0.3
800
+ domain_violations.append("physical")
801
+
802
+ # Check against stored common-sense rules
803
+ for rule in self._rules:
804
+ condition = rule["condition"].lower()
805
+ if condition in text:
806
+ # This is a recognized situation; check if response is plausible
807
+ pass # The existence of a matching rule INCREASES confidence
808
+
809
+ # Check context for additional signals
810
+ if context:
811
+ for warning in context.get("warnings", []):
812
+ issues.append(f"context_warning:{warning}")
813
+ confidence -= 0.1
814
+
815
+ confidence = max(0.0, min(1.0, confidence))
816
+
817
+ # Determine warning level
818
+ if confidence > 0.75:
819
+ warning_level = "none"
820
+ elif confidence > 0.55:
821
+ warning_level = "caution"
822
+ elif confidence > 0.35:
823
+ warning_level = "warning"
824
+ else:
825
+ warning_level = "alert"
826
+
827
+ passes = confidence > 0.5
828
+
829
+ # Compute rejection cost (ATC: rejection loop causes ATP depletion)
830
+ rejection_cost = 0.0
831
+ if not passes:
832
+ # Each issue costs energy; the rejection loop is the metabolic drain
833
+ rejection_cost = len(issues) * 0.05
834
+ self._rejection_accumulator += rejection_cost
835
+ # Decay accumulator slowly
836
+ self._rejection_accumulator *= 0.98
837
+ else:
838
+ # Passing reduces accumulated rejection stress
839
+ self._rejection_accumulator *= 0.9
840
+
841
+ if warning_level in ("warning", "alert"):
842
+ self._anomaly_history.append({
843
+ "stimulus": stimulus[:100],
844
+ "issues": issues,
845
+ "timestamp": time.time(),
846
+ })
847
+
848
+ if issues:
849
+ logger.debug(
850
+ "Common sense check: %s (confidence=%.2f, issues=%s)",
851
+ warning_level, confidence, issues,
852
+ )
853
+
854
+ return RealityCheckResult(
855
+ passes_reality_check=passes,
856
+ deviation_score=1.0 - confidence,
857
+ warnings=issues,
858
+ warning_level=warning_level,
859
+ domain_violations=domain_violations,
860
+ rejection_cost=rejection_cost + self._rejection_accumulator * 0.1,
861
+ )
862
+
863
+ def discover_pattern(self, observation: Dict[str, Any]) -> bool:
864
+ """Learn a new common-sense pattern from repeated observation."""
865
+ pattern = observation.get("pattern", "unknown")
866
+ domain = observation.get("domain", "abstract")
867
+ new_rule = {
868
+ "domain": domain,
869
+ "condition": observation.get("condition", "unknown"),
870
+ "pattern": pattern,
871
+ "response": observation.get("response", "observe more"),
872
+ "confidence": observation.get("confidence", "0.60"),
873
+ }
874
+ # Check if we already have this pattern
875
+ for rule in self._rules:
876
+ if rule["pattern"] == pattern and rule["domain"] == domain:
877
+ return False
878
+ self._rules.append(new_rule)
879
+ logger.debug("Discovered new common-sense pattern: %s:%s", domain, pattern)
880
+ return True
881
+
882
+ def get_rejection_accumulator(self) -> float:
883
+ """Return the accumulated rejection stress (ATC: feeds metabolic exhaustion)."""
884
+ return self._rejection_accumulator
885
+
886
+
887
+ # ===================================================================
888
+ # SECTION 7 — AnalyticalEngine
889
+ # ===================================================================
890
+
891
+ class AnalyticalEngine:
892
+ """Layer 4 support: Multi-scale analysis for metacognitive processing.
893
+
894
+ ATC mapping: Breaks down situations at multiple scales (Marr's
895
+ tri-level: computational, algorithmic, physical). The analysis_depth
896
+ output feeds metacognitive_depth_mod in the MetacognitiveSubstrate.
897
+ Emergent insights can trigger the irrational spark if they reveal
898
+ a prediction collapse that the subconscious missed.
899
+
900
+ Rewritten from AnalysisAgent. No CLI, no emoji, no threading.
901
+ """
902
+
903
+ def __init__(self) -> None:
904
+ self._history: deque = deque(maxlen=200)
905
+ self._preferred_depth: float = 0.7
906
+
907
+ def analyze(self, stimulus: str, context: Optional[Dict[str, Any]] = None) -> AnalysisEngineResult:
908
+ """Perform multi-scale analysis on the stimulus.
909
+
910
+ Marr's tri-level applied to any cognitive problem:
911
+ 1. Computational: What is the problem? What is the goal?
912
+ 2. Algorithmic: How is it solved? What strategy?
913
+ 3. Physical: What implements it? What substrate?
914
+
915
+ Returns analysis depth, confidence, and emergent insights.
916
+ """
917
+ text = stimulus.lower()
918
+ words = text.split()
919
+ word_count = len(words)
920
+
921
+ # Estimate complexity
922
+ unique_words = len(set(words))
923
+ lexical_diversity = unique_words / max(1, word_count)
924
+ question_markers = sum(1 for w in words if w in ("what", "how", "why", "when", "where", "who", "which"))
925
+ negation_markers = sum(1 for w in words if w in ("not", "no", "never", "none", "without"))
926
+ conditional_markers = sum(1 for w in words if w in ("if", "then", "else", "unless", "whether"))
927
+
928
+ complexity = min(1.0, (
929
+ lexical_diversity * 0.3 +
930
+ min(question_markers, 3) / 3.0 * 0.3 +
931
+ min(negation_markers, 2) / 2.0 * 0.2 +
932
+ min(conditional_markers, 2) / 2.0 * 0.2
933
+ ))
934
+
935
+ # Classify problem type
936
+ problem_type = self._classify_problem(text)
937
+
938
+ # Determine analysis depth based on complexity and preference
939
+ analysis_depth = min(1.0, complexity * 0.7 + self._preferred_depth * 0.3)
940
+
941
+ # Reasoning confidence decreases with complexity
942
+ reasoning_confidence = max(0.2, 0.9 - complexity * 0.5)
943
+
944
+ # Multi-scale analysis
945
+ scales_analyzed = []
946
+
947
+ # Computational level: what is the problem?
948
+ comp_confidence = min(0.95, 0.7 + question_markers * 0.1)
949
+ scales_analyzed.append("computational")
950
+
951
+ # Algorithmic level: how to solve it
952
+ algo_confidence = max(0.3, 0.7 - complexity * 0.3)
953
+ scales_analyzed.append("algorithmic")
954
+
955
+ # Physical level: what implements it (usually least certain)
956
+ phys_confidence = max(0.2, 0.5 - complexity * 0.2)
957
+ scales_analyzed.append("physical")
958
+
959
+ # Integration score
960
+ integration_score = (comp_confidence + algo_confidence + phys_confidence) / 3.0
961
+
962
+ # Discover emergent insights
963
+ emergent_insights = []
964
+ if complexity > 0.7 and reasoning_confidence < 0.5:
965
+ emergent_insights.append("high_complexity_low_confidence: situation may require non-standard approach")
966
+ if question_markers > 2:
967
+ emergent_insights.append("multi_question: nested inquiry detected, layered analysis recommended")
968
+ if negation_markers > 1 and conditional_markers > 0:
969
+ emergent_insights.append("conditional_negation: counterfactual reasoning may be needed")
970
+ if lexical_diversity > 0.8 and word_count > 10:
971
+ emergent_insights.append("high_diversity_long_input: rich semantic content, deep processing warranted")
972
+ if context and context.get("prediction_failed"):
973
+ emergent_insights.append("prediction_mismatch: analytical re-evaluation triggered by prediction failure")
974
+
975
+ # Check if analysis reveals something the subconscious missed
976
+ if context:
977
+ gut_safety = context.get("gut_safety", 0.5)
978
+ if gut_safety > 0.7 and complexity > 0.6:
979
+ emergent_insights.append(
980
+ "safety_complexity_mismatch: gut says safe but situation is complex, verify"
981
+ )
982
+
983
+ self._history.append({
984
+ "stimulus": stimulus[:80],
985
+ "complexity": complexity,
986
+ "depth": analysis_depth,
987
+ "insights": len(emergent_insights),
988
+ "timestamp": time.time(),
989
+ })
990
+
991
+ return AnalysisEngineResult(
992
+ analysis_depth=analysis_depth,
993
+ reasoning_confidence=reasoning_confidence,
994
+ emergent_insights=emergent_insights,
995
+ problem_type=problem_type,
996
+ complexity_estimate=complexity,
997
+ integration_score=integration_score,
998
+ scales_analyzed=scales_analyzed,
999
+ )
1000
+
1001
+ def _classify_problem(self, text: str) -> str:
1002
+ """Classify the type of cognitive problem."""
1003
+ classification_rules = [
1004
+ (["choose", "select", "decide", "pick", "prefer"], "decision"),
1005
+ (["predict", "forecast", "estimate", "expect", "guess"], "prediction"),
1006
+ (["optim", "maxim", "minim", "improve", "best"], "optimization"),
1007
+ (["classif", "categoriz", "identify", "recognize", "detect"], "classification"),
1008
+ (["understand", "explain", "interpret", "meaning", "why"], "interpretation"),
1009
+ (["create", "generat", "design", "invent", "compose"], "creation"),
1010
+ (["analyz", "examin", "investigat", "study", "review"], "analysis"),
1011
+ (["compar", "contrast", "differ", "versus", "vs"], "comparison"),
1012
+ ]
1013
+ for keywords, ptype in classification_rules:
1014
+ if any(kw in text for kw in keywords):
1015
+ return ptype
1016
+ return "unknown"
1017
+
1018
+ def set_depth_preference(self, depth: float) -> None:
1019
+ """Adjust preferred analysis depth (0=shallow, 1=deep)."""
1020
+ self._preferred_depth = max(0.0, min(1.0, depth))
1021
+
1022
+
1023
+ # ===================================================================
1024
+ # SECTION 8 — CognitiveLayer2Orchestrator
1025
+ # ===================================================================
1026
+
1027
+ class CognitiveLayer2Orchestrator:
1028
+ """Orchestrates all Layer 2 cognitive components in parallel (sequential
1029
+ in code, conceptually parallel as in the ATC subconscious matrix).
1030
+
1031
+ This is the entry point that the middleware calls.
1032
+
1033
+ Usage in middleware::
1034
+
1035
+ cognitive = CognitiveLayer2Orchestrator()
1036
+ layer2_result = cognitive.process(stimulus_text, context)
1037
+ # layer2_result.prediction_error -> feeds DissolutionEngine (friction)
1038
+ # layer2_result.valence/arousal -> feeds phi_neuro (Theorem 2)
1039
+ # layer2_result.gut_safety -> feeds TRN predictive gating
1040
+ # layer2_result.passes_reality_check -> feeds self-understanding (Layer 4)
1041
+ # layer2_result.thermodynamic_cost -> feeds allostatic load (Theorem 3)
1042
+
1043
+ ATC mapping: This orchestrator IS the 'subconscious Layer 2 parallel
1044
+ processing matrix' from the Perfect Breakfast scenario. Each subsystem
1045
+ runs independently and their outputs are merged into a single Layer2Result
1046
+ that the rest of the ATC pipeline consumes.
1047
+ """
1048
+
1049
+ def __init__(self, max_memory_entries: int = 5000) -> None:
1050
+ self.pattern_matcher = SubconsciousPatternMatch(max_memory_entries=max_memory_entries)
1051
+ self.emotional_bridge = EmotionalBridge()
1052
+ self.gut_check = IntuitiveGutCheck()
1053
+ self.reality_filter = CommonSenseRealityFilter()
1054
+ self.analytical_engine = AnalyticalEngine()
1055
+ self._process_count: int = 0
1056
+ self._total_cost: float = 0.0
1057
+ logger.debug("CognitiveLayer2Orchestrator initialized with 5 subsystems")
1058
+
1059
+ def process(
1060
+ self,
1061
+ stimulus: str,
1062
+ context: Optional[Dict[str, Any]] = None,
1063
+ ) -> Layer2Result:
1064
+ """Run all Layer 2 cognitive subsystems and return unified result.
1065
+
1066
+ Subsystems run sequentially (Python is sync) but are logically
1067
+ independent -- no subsystem reads another's output within the
1068
+ same cycle. This mirrors biological parallel processing where
1069
+ the thalamus gates simultaneous subconscious streams.
1070
+ """
1071
+ ctx = context or {}
1072
+ start = time.time()
1073
+
1074
+ # 1. Subconscious pattern matching (memory + intuition)
1075
+ pattern_result = self.pattern_matcher.match(stimulus, ctx)
1076
+
1077
+ # 2. Emotional bridge (EI -> BELBIC -> phi_neuro)
1078
+ emotional_result = self.emotional_bridge.process(stimulus, ctx)
1079
+
1080
+ # 3. Intuitive gut-check (System 1 -> TRN gating)
1081
+ gut_result = self.gut_check.check(stimulus, ctx)
1082
+
1083
+ # 4. Common sense reality filter (reality check -> self-understanding)
1084
+ reality_result = self.reality_filter.check(stimulus, ctx)
1085
+
1086
+ # 5. Analytical engine (metacognitive support -> Layer 4)
1087
+ analysis_ctx = {
1088
+ **ctx,
1089
+ "gut_safety": gut_result.predicted_safety,
1090
+ "prediction_failed": pattern_result.is_novel,
1091
+ }
1092
+ analysis_result = self.analytical_engine.analyze(stimulus, analysis_ctx)
1093
+
1094
+ # Compute prediction_error from pattern match and reality check
1095
+ # If pattern matching is confident but reality check fails,
1096
+ # we have a high prediction error (prediction collapse)
1097
+ if pattern_result.prediction_confidence > 0.5 and not reality_result.passes_reality_check:
1098
+ prediction_error = pattern_result.prediction_confidence * (1.0 - reality_result.passes_reality_check)
1099
+ elif pattern_result.is_novel:
1100
+ prediction_error = 0.5 # Novel = moderate surprise
1101
+ else:
1102
+ prediction_error = max(0.0, 1.0 - pattern_result.prediction_confidence) * 0.5
1103
+
1104
+ prediction_error = max(0.0, min(1.0, prediction_error))
1105
+
1106
+ # Compute thermodynamic cost (ATC: ATP consumption)
1107
+ # Each subsystem has an energy cost; novelty and high arousal increase it
1108
+ base_cost = 0.02 # Baseline ATP cost
1109
+ pattern_cost = 0.01 * len(pattern_result.matched_memory_refs)
1110
+ emotion_cost = 0.015 * emotional_result.arousal
1111
+ gut_cost = gut_result.energy_cost
1112
+ reality_cost = reality_result.rejection_cost
1113
+ analysis_cost = 0.02 * analysis_result.analysis_depth
1114
+ novelty_surcharge = 0.03 * pattern_result.novelty_score
1115
+ thermodynamic_cost = (
1116
+ base_cost + pattern_cost + emotion_cost + gut_cost
1117
+ + reality_cost + analysis_cost + novelty_surcharge
1118
+ )
1119
+ thermodynamic_cost = min(0.5, thermodynamic_cost) # Cap at 0.5
1120
+
1121
+ # Accumulate tracking
1122
+ self._process_count += 1
1123
+ self._total_cost += thermodynamic_cost
1124
+
1125
+ elapsed_ms = (time.time() - start) * 1000
1126
+
1127
+ if logger.isEnabledFor(logging.DEBUG):
1128
+ logger.debug(
1129
+ "Layer2 process: pred_conf=%.2f valence=%.2f arousal=%.2f "
1130
+ "gut_safety=%.2f reality=%s novel=%s cost=%.4f time=%.1fms",
1131
+ pattern_result.prediction_confidence,
1132
+ emotional_result.valence,
1133
+ emotional_result.arousal,
1134
+ gut_result.predicted_safety,
1135
+ reality_result.passes_reality_check,
1136
+ pattern_result.is_novel,
1137
+ thermodynamic_cost,
1138
+ elapsed_ms,
1139
+ )
1140
+
1141
+ return Layer2Result(
1142
+ prediction_confidence=pattern_result.prediction_confidence,
1143
+ prediction_label=pattern_result.prediction_label,
1144
+ valence=emotional_result.valence,
1145
+ arousal=emotional_result.arousal,
1146
+ emotion_label=emotional_result.emotion_label,
1147
+ gut_safety=gut_result.predicted_safety,
1148
+ intuition_confidence=gut_result.gut_confidence,
1149
+ passes_reality_check=reality_result.passes_reality_check,
1150
+ common_sense_warnings=reality_result.warnings,
1151
+ is_novel=pattern_result.is_novel,
1152
+ matched_patterns=pattern_result.matched_patterns,
1153
+ thermodynamic_cost=thermodynamic_cost,
1154
+ prediction_error=prediction_error,
1155
+ pattern_match=pattern_result,
1156
+ emotional_bridge=emotional_result,
1157
+ gut_check=gut_result,
1158
+ reality_check=reality_result,
1159
+ analysis=analysis_result,
1160
+ )
1161
+
1162
+ def store_memory(
1163
+ self,
1164
+ content: str,
1165
+ tags: Optional[List[str]] = None,
1166
+ importance: float = 0.5,
1167
+ valence: float = 0.0,
1168
+ arousal: float = 0.0,
1169
+ ) -> str:
1170
+ """Store a memory in the pattern matcher for future matching."""
1171
+ return self.pattern_matcher.store(content, tags, importance, valence, arousal)
1172
+
1173
+ def get_metrics(self) -> Dict[str, Any]:
1174
+ """Return diagnostic metrics for all subsystems."""
1175
+ return {
1176
+ "total_processes": self._process_count,
1177
+ "average_thermodynamic_cost": self._total_cost / max(1, self._process_count),
1178
+ "memory_count": self.pattern_matcher.get_memory_count(),
1179
+ "emotional_complexity": self.emotional_bridge.get_complexity(),
1180
+ "gut_check_accuracy": self.gut_check.get_accuracy(),
1181
+ "rejection_accumulator": self.reality_filter.get_rejection_accumulator(),
1182
+ }