Skip to content

Commit cdbe130

Browse files
committed
Further upgrades
1 parent f63fee3 commit cdbe130

3 files changed

Lines changed: 171 additions & 29 deletions

File tree

harmonizer_v84/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@
4040
from harmonizer_v84.consciousness import consciousness_metric, check_uncertainty_principle
4141
from harmonizer_v84.phase_detector import detect_phase, Phase
4242
from harmonizer_v84.phi_normalizer import phi_normalize, normalize_coordinates
43-
from harmonizer_v84.code_analyzer import analyze_file, analyze_source, V73CodeAnalyzer
43+
from harmonizer_v84.code_analyzer import analyze_file, analyze_source, V84CodeAnalyzer
44+
45+
# Backward compatibility alias
46+
V73CodeAnalyzer = V84CodeAnalyzer
4447
from harmonizer_v84.vocabulary import (
4548
PROGRAMMING_VERBS,
4649
POWER_VERBS,
@@ -79,6 +82,7 @@
7982
"analyze_file",
8083
"analyze_source",
8184
"V73CodeAnalyzer",
85+
"V84CodeAnalyzer",
8286
"DriftDetector",
8387
"DriftAnalysis",
8488
# Vocabulary

harmonizer_v84/code_analyzer.py

Lines changed: 90 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
"""
2-
V7.3 Code Analyzer - Extract LJPW from Python Code
2+
V8.4 Code Analyzer - Extract LJPW from Python Code
33
4-
Based on the V7.3 insight that Power (P) and Wisdom (W) are FUNDAMENTAL,
5-
while Love (L) and Justice (J) are EMERGENT.
4+
Based on the V8.4 Framework with the Generative Equation:
5+
- P (Power) and W (Wisdom) are FUNDAMENTAL
6+
- L (Love) and J (Justice) are EMERGENT
7+
- Life Inequality: L^n > φ^d determines viability
8+
- Perceptual Radiance: Semantic intensity of code
69
7-
Mapping strategy:
8-
- P (Power): Execution, transformation, state changes, side effects
9-
- W (Wisdom): Knowledge, patterns, documentation, type info, returns
10-
- L (Love): Calculated from W (L emerges from wisdom correlations)
11-
- J (Justice): Calculated from P (J emerges from power symmetries)
10+
V8.4 Additions:
11+
- life_inequality_ratio: Code's L^n / φ^d ratio
12+
- perceptual_radiance: Semantic weight for visualization
13+
- hope_probability: Mathematical hope of improvement
1214
13-
Based on: LJPW_FRAMEWORK_V7.3_COMPLETE_UNIFIED_PLUS.md
15+
Based on: LJPW_FRAMEWORK_V8.4_COMPLETE_UNIFIED_PLUS.md
1416
"""
1517

1618
import ast
@@ -24,6 +26,13 @@
2426
from harmonizer_v84.phase_detector import detect_phase, Phase, analyze_phase
2527
from harmonizer_v84.phi_normalizer import normalize_coordinates
2628
from harmonizer_v84.bricks_mortar import function_primality, BrickAnalysis
29+
from harmonizer_v84.generative import (
30+
is_autopoietic,
31+
perceptual_radiance,
32+
semantic_salience,
33+
hope_calculus,
34+
LifeInequalityResult,
35+
)
2736

2837

2938
@dataclass
@@ -38,14 +47,23 @@ class FunctionAnalysis:
3847
power_raw: float
3948
wisdom_raw: float
4049

41-
# V7.3 framework result
50+
# V8.4 framework result
4251
framework: LJPWFramework = None
4352

4453
# Consciousness and phase
4554
consciousness: float = 0.0
4655
consciousness_level: ConsciousnessLevel = ConsciousnessLevel.NON_CONSCIOUS
4756
phase: Phase = Phase.ENTROPIC
4857

58+
# V8.4: Life Inequality (L^n > φ^d)
59+
life_inequality_ratio: float = 1.0
60+
life_phase: str = "HOMEOSTATIC"
61+
is_alive: bool = True
62+
63+
# V8.4: Perceptual Radiance (for visualization)
64+
semantic_salience: float = 0.5
65+
perceptual_radiance: float = 1.0
66+
4967
# Bricks & Mortar
5068
brick_analysis: BrickAnalysis = None
5169

@@ -62,6 +80,28 @@ def __post_init__(self):
6280
)
6381
self.phase = detect_phase(H, self.framework.L)
6482

83+
# V8.4: Calculate Life Inequality
84+
# n = complexity (iterations of development)
85+
# d = distance from natural equilibrium (technical debt proxy)
86+
L_coeff = max(1.0, 1.0 + self.framework.L * 0.5) # Love as growth coefficient
87+
n = max(1, len(self.power_signals) + len(self.wisdom_signals)) # Development iterations
88+
d = self.framework.distance_from_equilibrium() # Distance as decay factor
89+
life_result = is_autopoietic(L=L_coeff, n=n, d=d)
90+
self.life_inequality_ratio = life_result.ratio
91+
self.life_phase = life_result.phase
92+
self.is_alive = life_result.is_alive
93+
94+
# V8.4: Calculate Perceptual Radiance
95+
self.semantic_salience = semantic_salience(
96+
self.framework.L, self.framework.P, self.framework.W, self.framework.J
97+
)
98+
# Physical radiance approximated as consciousness
99+
self.perceptual_radiance = perceptual_radiance(
100+
L_phys=min(1.0, self.consciousness + 0.3), # Base physical radiance
101+
S=self.semantic_salience,
102+
kappa_sem=H # Semantic curvature from Harmony
103+
)
104+
65105

66106
@dataclass
67107
class FileAnalysis:
@@ -78,6 +118,16 @@ class FileAnalysis:
78118
overall_consciousness: float = 0.0
79119
overall_phase: Phase = Phase.ENTROPIC
80120

121+
# V8.4: File-level Life Inequality
122+
file_life_ratio: float = 1.0
123+
file_life_phase: str = "HOMEOSTATIC"
124+
file_is_alive: bool = True
125+
avg_perceptual_radiance: float = 1.0
126+
127+
# V8.4: Hope metric (can this file improve?)
128+
hope_probability: float = 0.5
129+
hope_interpretation: str = ""
130+
81131
# File-level stats
82132
total_lines: int = 0
83133
import_count: int = 0
@@ -98,13 +148,35 @@ def __post_init__(self):
98148
)
99149
self.overall_phase = detect_phase(H, self.overall_framework.L)
100150

151+
# V8.4: File-level Life Inequality (aggregate)
152+
ratios = [f.life_inequality_ratio for f in self.functions]
153+
self.file_life_ratio = sum(ratios) / len(ratios)
154+
alive_count = sum(1 for f in self.functions if f.is_alive)
155+
self.file_is_alive = alive_count > len(self.functions) / 2
156+
self.file_life_phase = "AUTOPOIETIC" if self.file_is_alive and self.file_life_ratio > 1.1 else "HOMEOSTATIC" if self.file_life_ratio > 0.9 else "ENTROPIC"
157+
158+
# V8.4: Average Perceptual Radiance
159+
self.avg_perceptual_radiance = sum(f.perceptual_radiance for f in self.functions) / len(self.functions)
160+
161+
# V8.4: Calculate Hope
162+
L_coeff = max(1.0, 1.0 + self.overall_framework.L * 0.5)
163+
d = self.overall_framework.distance_from_equilibrium()
164+
hope_result = hope_calculus(L=L_coeff, d=d, current_n=len(self.functions))
165+
self.hope_probability = hope_result.probability_of_success
166+
self.hope_interpretation = hope_result.interpretation
101167

102-
class V73CodeAnalyzer(ast.NodeVisitor):
168+
169+
class V84CodeAnalyzer(ast.NodeVisitor):
103170
"""
104-
V7.3 Code Analyzer - Extracts P and W from Python AST.
171+
V8.4 Code Analyzer - Extracts P and W from Python AST with Generative Equation.
172+
173+
The key insight: Only measure P and W directly.
174+
L and J are CALCULATED (emergent), not measured.
105175
106-
The key V7.3 insight: Only measure P and W directly.
107-
L and J are CALCULATED, not measured.
176+
V8.4 Additions:
177+
- Life Inequality score: L^n > φ^d
178+
- Perceptual Radiance: Semantic intensity for visualization
179+
- Hope calculation: Can this code improve?
108180
109181
Power (P) indicators:
110182
- Assignments (state changes)
@@ -395,19 +467,19 @@ def generic_visit(self, node: ast.AST):
395467

396468
def analyze_file(filepath: str) -> FileAnalysis:
397469
"""
398-
Analyze a Python file using V7.3 framework.
470+
Analyze a Python file using V8.4 framework.
399471
400472
Args:
401473
filepath: Path to Python file
402474
403475
Returns:
404-
FileAnalysis with all function analyses and overall metrics
476+
FileAnalysis with all function analyses, Life Inequality, and Hope metrics
405477
"""
406478
path = Path(filepath)
407479
source = path.read_text(encoding="utf-8")
408480
tree = ast.parse(source)
409481

410-
analyzer = V73CodeAnalyzer()
482+
analyzer = V84CodeAnalyzer()
411483
functions = []
412484
classes = []
413485
import_count = 0
@@ -454,7 +526,7 @@ def analyze_source(source: str, filename: str = "<string>") -> FileAnalysis:
454526
FileAnalysis with all function analyses
455527
"""
456528
tree = ast.parse(source)
457-
analyzer = V73CodeAnalyzer()
529+
analyzer = V84CodeAnalyzer()
458530
functions = []
459531
classes = []
460532

harmonizer_v84/drift_detector.py

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
"""
2-
V7.3 Drift Detector - Git-based Semantic Drift Analysis
2+
V8.4 Drift Detector - Git-based Semantic Drift Analysis with Hope
33
4-
Tracks how codebase consciousness and phase evolve over time.
5-
Detects semantic drift, phase transitions, and "death spirals".
4+
Tracks how codebase consciousness, phase, and hope evolve over time.
5+
Detects semantic drift, phase transitions, death spirals, and recovery potential.
66
7-
Key V7.3 insights:
7+
V8.4 Additions:
8+
- Hope Probability: Mathematical hope of recovery
9+
- Life Inequality tracking: L^n > φ^d trend
10+
- Predictive recovery analysis
11+
12+
Key insights:
813
- Consciousness (C) should trend upward for healthy projects
9-
- Phase transitions matter: EntropicHomeostaticAutopoietic
14+
- Phase transitions matter: EntropicHomeostaticAutopoietic
1015
- "Death spiral" = sustained C decline + phase regression
16+
- Hope = P(L^n > φ^d as n → ∞) predicts recovery potential
1117
12-
Based on: v5.1's legacy_mapper.py + LJPW V7.3 Framework
18+
Based on: LJPW_FRAMEWORK_V8.4_COMPLETE_UNIFIED_PLUS.md
1319
"""
1420

1521
import subprocess
@@ -24,6 +30,7 @@
2430
from harmonizer_v84.ljpw_core import LJPWFramework
2531
from harmonizer_v84.phase_detector import Phase, detect_phase
2632
from harmonizer_v84.consciousness import consciousness_metric, ConsciousnessLevel
33+
from harmonizer_v84.generative import hope_calculus, is_autopoietic
2734

2835

2936
@dataclass
@@ -41,15 +48,19 @@ class CommitSnapshot:
4148
P: float = 0.0
4249
W: float = 0.0
4350

44-
# V7.3 metrics
51+
# V8.4 metrics
4552
harmony: float = 0.0
4653
consciousness: float = 0.0
4754
phase: Phase = Phase.ENTROPIC
4855

56+
# V8.4: Life Inequality and Hope
57+
life_ratio: float = 1.0
58+
hope_probability: float = 0.5
59+
4960

5061
@dataclass
5162
class DriftAnalysis:
52-
"""Analysis of semantic drift over time."""
63+
"""Analysis of semantic drift over time with hope prediction."""
5364

5465
file_path: str
5566
snapshots: List[CommitSnapshot] = field(default_factory=list)
@@ -59,6 +70,12 @@ class DriftAnalysis:
5970
consciousness_trend: float = 0.0 # Positive = improving
6071
phase_transitions: List[Tuple[str, Phase, Phase]] = field(default_factory=list)
6172

73+
# V8.4: Hope-based predictions
74+
current_hope: float = 0.5
75+
hope_trend: float = 0.0 # Positive = increasing hope
76+
recovery_possible: bool = True
77+
predicted_recovery_iterations: int = -1
78+
6279
# Health indicators
6380
is_healthy: bool = True
6481
health_issues: List[str] = field(default_factory=list)
@@ -93,6 +110,23 @@ def compute_metrics(self):
93110
)
94111
)
95112

113+
# V8.4: Hope-based predictions
114+
if last.hope_probability > 0:
115+
self.current_hope = last.hope_probability
116+
self.hope_trend = last.hope_probability - first.hope_probability
117+
self.recovery_possible = last.hope_probability > 0.3
118+
119+
# Calculate predicted recovery iterations
120+
if last.L > 0 and not self.is_healthy:
121+
L_coeff = max(1.0, 1.0 + last.L * 0.5)
122+
d = abs(last.L - 0.618) # Distance from equilibrium
123+
if L_coeff > 1:
124+
from math import log, ceil
125+
# n needed for L^n > φ^d
126+
from harmonizer_v84.constants import PHI
127+
n_needed = ceil((d * log(PHI)) / log(L_coeff)) if L_coeff > 1 else -1
128+
self.predicted_recovery_iterations = max(0, n_needed - len(self.snapshots))
129+
96130
# Health assessment
97131
self._assess_health()
98132

@@ -131,6 +165,14 @@ def _assess_health(self):
131165
if all(s.consciousness < 0.1 for s in self.snapshots):
132166
self.health_issues.append("Never crossed consciousness threshold")
133167

168+
# V8.4: Check hope trajectory
169+
if self.hope_trend < -0.1:
170+
self.health_issues.append(f"Hope declining: {self.hope_trend:+.2f}")
171+
172+
if not self.recovery_possible:
173+
self.is_healthy = False
174+
self.health_issues.append("Recovery mathematically unlikely (Hope < 0.3)")
175+
134176

135177
@dataclass
136178
class CodebaseEvolution:
@@ -151,13 +193,14 @@ class CodebaseEvolution:
151193

152194
class DriftDetector:
153195
"""
154-
Git-based semantic drift detector for V7.3.
196+
Git-based semantic drift detector for V8.4.
155197
156198
Analyzes how code evolves over git history and tracks:
157199
- LJPW coordinate changes
158200
- Consciousness (C) trend
159201
- Phase transitions
160-
- "Death spiral" detection
202+
- Death spiral detection
203+
- V8.4: Hope-based recovery prediction
161204
"""
162205

163206
def __init__(self, repo_path: str):
@@ -255,6 +298,13 @@ def analyze_file_history(self, file_path: str, max_commits: int = 50) -> DriftAn
255298
except:
256299
date = datetime.now()
257300

301+
# V8.4: Calculate Life Inequality and Hope
302+
L_coeff = max(1.0, 1.0 + fw.L * 0.5)
303+
d = fw.distance_from_equilibrium()
304+
n = len(analysis.functions) if analysis.functions else 1
305+
life_result = is_autopoietic(L=L_coeff, n=n, d=d)
306+
hope_result = hope_calculus(L=L_coeff, d=d, current_n=n)
307+
258308
snapshot = CommitSnapshot(
259309
commit_hash=commit["hash"],
260310
commit_date=date,
@@ -267,6 +317,8 @@ def analyze_file_history(self, file_path: str, max_commits: int = 50) -> DriftAn
267317
harmony=H,
268318
consciousness=C,
269319
phase=phase,
320+
life_ratio=life_result.ratio,
321+
hope_probability=hope_result.probability_of_success,
270322
)
271323
drift.snapshots.append(snapshot)
272324

@@ -394,6 +446,20 @@ def print_drift_report(drift: DriftAnalysis):
394446
for issue in drift.health_issues:
395447
print(f" • {issue}")
396448

449+
# V8.4: Hope Analysis
450+
print(f"\n 🌟 HOPE ANALYSIS:")
451+
hope_icon = "🔆" if drift.current_hope > 0.7 else "🔅" if drift.current_hope > 0.3 else "💀"
452+
print(f" Current Hope: {hope_icon} {drift.current_hope:.0%}")
453+
hope_trend_icon = "📈" if drift.hope_trend > 0 else "📉"
454+
print(f" Hope Trend: {hope_trend_icon} {drift.hope_trend:+.2f}")
455+
if drift.recovery_possible:
456+
if drift.predicted_recovery_iterations > 0:
457+
print(f" Recovery ETA: ~{drift.predicted_recovery_iterations} iterations")
458+
else:
459+
print(f" Recovery: On track ✓")
460+
else:
461+
print(f" Recovery: Unlikely without intervention")
462+
397463
# First/Last comparison
398464
if len(drift.snapshots) >= 2:
399465
first = drift.snapshots[0]

0 commit comments

Comments
 (0)