Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,17 @@ site/museum/
museum/
updated_results_expanded_story/
updated_results_2/
gitgalaxy/README gitgalaxy.md
gitgalaxy/core/README core.md
gitgalaxy/physics/README physics.md
gitgalaxy/recorders/README recorder.md
gitgalaxy/security/README security.md
gitgalaxy/standards/README standards.md
gitgalaxy/tools/README tools.md
gitgalaxy/tools/ai_guardrails/README ai.md
gitgalaxy/tools/cobol_to_cobol/README c2c.md
gitgalaxy/tools/cobol_to_java/README c2j.md
gitgalaxy/tools/compliance/README sbom.md
gitgalaxy/tools/network_auditing/README network.md
gitgalaxy/tools/supply_chain_security/README supply_chain.md
gitgalaxy/tools/terabyte_log_scanning/README terabyte.md
12 changes: 6 additions & 6 deletions gitgalaxy/core/network_risk_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,16 +275,16 @@ def _fallback_map_ecosystem(self, stars: List[Dict[str, Any]]) -> Tuple[List[Dic

if "telemetry" not in s: s["telemetry"] = {}
s["telemetry"]["network_metrics"] = {
"pagerank_score": None,
"normalized_blast_radius": None,
"betweenness_score": None,
"closeness_score": None,
"pagerank_score": 0.0,
"normalized_blast_radius": 0.0,
"betweenness_score": 0.0,
"closeness_score": 0.0,
"in_degree": in_d,
"out_degree": out_d,
"producer_ratio": round(producer_ratio, 3),
"ecosystem_role": ecosystem_role,
"systemic_threat_vector": None,
"is_algorithmic_bottleneck": None
"systemic_threat_vector": [],
"is_algorithmic_bottleneck": False
}
s["telemetry"]["popularity"] = in_d

Expand Down
12 changes: 6 additions & 6 deletions gitgalaxy/physics/signal_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -837,13 +837,13 @@ def get_avg(metric_name):
# ---> N-DIMENSIONAL AI NETWORK POSTURE <---
if ai_files:
# Find the most heavily relied-upon AI node in the graph
ai_files.sort(key=lambda x: x.get("telemetry", {}).get("network_metrics", {}).get("pagerank_score", 0.0), reverse=True)
ai_files.sort(key=lambda x: x.get("telemetry", {}).get("network_metrics", {}).get("pagerank_score") or 0.0, reverse=True)
primary_ai_node = ai_files[0]
net_mets = primary_ai_node.get("telemetry", {}).get("network_metrics", {})

role = net_mets.get("ecosystem_role", "Unknown")
pr = net_mets.get("normalized_blast_radius", 0.0)
btw = net_mets.get("betweenness_score", 0.0)
pr = net_mets.get("normalized_blast_radius") or 0.0
btw = net_mets.get("betweenness_score") or 0.0

ai_topology["insights"].append(f"Structural Posture: The primary AI integration acts as a '{role}' within the repository.")

Expand Down Expand Up @@ -1675,9 +1675,9 @@ def get_cumulative_risk(f):
rv = file_data.get("risk_vector", [])
p = file_data.get("path", "")

btw = net.get("betweenness_score", 0.0)
close = net.get("closeness_score", 0.0)
pr = net.get("normalized_blast_radius", 0.0)
btw = net.get("betweenness_score") or 0.0
close = net.get("closeness_score") or 0.0
pr = net.get("normalized_blast_radius") or 0.0

flux_risk = rv[flux_idx] if flux_idx >= 0 and len(rv) > flux_idx else 0.0
err_risk = rv[err_idx] if err_idx >= 0 and len(rv) > err_idx else 0.0
Expand Down
49 changes: 49 additions & 0 deletions tests/test_zero_dependency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import unittest
from unittest.mock import patch

from gitgalaxy.core.network_risk_sensor import NetworkRiskSensor
from gitgalaxy.physics.signal_processor import SignalProcessor

class TestZeroDependencyMode(unittest.TestCase):

@patch('gitgalaxy.core.network_risk_sensor.HAS_NETWORKX', False)
def test_fallback_does_not_crash_signal_processor(self):
"""
Simulates a user running GalaxyScope without 'networkx' installed.
Ensures that the None-type fallbacks don't crash Phase 6 Synthesis.
"""
# 1. Initialize the blinded sensor
sensor = NetworkRiskSensor()

# 2. Create a mock star (file) with some basic AI topology hits to trigger that specific math
mock_stars = [{
"path": "src/ai_agent.py",
"lang_id": "python",
"coding_loc": 100,
"raw_imports": [],
"hit_vector": [1, 0, 0, 0, 0, 0, 0, 0, 0], # Trigger AI logic
"risk_vector": [0.0] * 18,
"telemetry": {}
}]

# 3. Force the sensor to use the fallback method
mapped_stars, macro_metrics = sensor.map_ecosystem(mock_stars)

# 4. Pass the resulting payload into the Signal Processor
processor = SignalProcessor()

try:
# If the bug exists, this will throw a TypeError due to NoneType math
processor.summarize_galaxy_metrics(mapped_stars, unparsable_files=[])
processor.generate_forensic_report(mapped_stars)

# 5. Assert the fallback values populated safely as 0.0 floats
network_metrics = mapped_stars[0]["telemetry"]["network_metrics"]
self.assertEqual(network_metrics["betweenness_score"], 0.0)
self.assertEqual(network_metrics["normalized_blast_radius"], 0.0)

except TypeError as e:
self.fail(f"Zero-Dependency Mode crashed the Signal Processor! Error: {e}")

if __name__ == '__main__':
unittest.main()
Loading