diogenesis-sdk 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. diogenesis_sdk-0.1.0/LICENSE +21 -0
  2. diogenesis_sdk-0.1.0/PKG-INFO +91 -0
  3. diogenesis_sdk-0.1.0/README.md +72 -0
  4. diogenesis_sdk-0.1.0/diogenesis_sdk/__init__.py +52 -0
  5. diogenesis_sdk-0.1.0/diogenesis_sdk/agents/__init__.py +0 -0
  6. diogenesis_sdk-0.1.0/diogenesis_sdk/agents/swarm.py +152 -0
  7. diogenesis_sdk-0.1.0/diogenesis_sdk/agents/xenobot.py +366 -0
  8. diogenesis_sdk-0.1.0/diogenesis_sdk/baseline.py +76 -0
  9. diogenesis_sdk-0.1.0/diogenesis_sdk/core/__init__.py +0 -0
  10. diogenesis_sdk-0.1.0/diogenesis_sdk/core/classifier.py +104 -0
  11. diogenesis_sdk-0.1.0/diogenesis_sdk/core/config.py +62 -0
  12. diogenesis_sdk-0.1.0/diogenesis_sdk/core/event_buffer.py +52 -0
  13. diogenesis_sdk-0.1.0/diogenesis_sdk/engine.py +308 -0
  14. diogenesis_sdk-0.1.0/diogenesis_sdk/field/__init__.py +0 -0
  15. diogenesis_sdk-0.1.0/diogenesis_sdk/field/propagation.py +90 -0
  16. diogenesis_sdk-0.1.0/diogenesis_sdk/field/voltage.py +226 -0
  17. diogenesis_sdk-0.1.0/diogenesis_sdk/interceptors/__init__.py +0 -0
  18. diogenesis_sdk-0.1.0/diogenesis_sdk/interceptors/base.py +70 -0
  19. diogenesis_sdk-0.1.0/diogenesis_sdk/interceptors/file_hook.py +43 -0
  20. diogenesis_sdk-0.1.0/diogenesis_sdk/interceptors/import_hook.py +41 -0
  21. diogenesis_sdk-0.1.0/diogenesis_sdk/interceptors/network_hook.py +55 -0
  22. diogenesis_sdk-0.1.0/diogenesis_sdk/interceptors/subprocess_hook.py +69 -0
  23. diogenesis_sdk-0.1.0/diogenesis_sdk/policy/__init__.py +0 -0
  24. diogenesis_sdk-0.1.0/diogenesis_sdk/policy/engine.py +58 -0
  25. diogenesis_sdk-0.1.0/diogenesis_sdk/policy/pattern.py +157 -0
  26. diogenesis_sdk-0.1.0/diogenesis_sdk/policy/response.py +55 -0
  27. diogenesis_sdk-0.1.0/diogenesis_sdk/timing/__init__.py +0 -0
  28. diogenesis_sdk-0.1.0/diogenesis_sdk/timing/fibonacci.py +206 -0
  29. diogenesis_sdk-0.1.0/diogenesis_sdk/timing/scheduler.py +154 -0
  30. diogenesis_sdk-0.1.0/diogenesis_sdk.egg-info/PKG-INFO +91 -0
  31. diogenesis_sdk-0.1.0/diogenesis_sdk.egg-info/SOURCES.txt +47 -0
  32. diogenesis_sdk-0.1.0/diogenesis_sdk.egg-info/dependency_links.txt +1 -0
  33. diogenesis_sdk-0.1.0/diogenesis_sdk.egg-info/top_level.txt +1 -0
  34. diogenesis_sdk-0.1.0/pyproject.toml +25 -0
  35. diogenesis_sdk-0.1.0/setup.cfg +4 -0
  36. diogenesis_sdk-0.1.0/tests/test_engine.py +294 -0
  37. diogenesis_sdk-0.1.0/tests/test_fibonacci.py +130 -0
  38. diogenesis_sdk-0.1.0/tests/test_file_hook.py +81 -0
  39. diogenesis_sdk-0.1.0/tests/test_graduated_response.py +65 -0
  40. diogenesis_sdk-0.1.0/tests/test_import_hook.py +64 -0
  41. diogenesis_sdk-0.1.0/tests/test_network_hook.py +55 -0
  42. diogenesis_sdk-0.1.0/tests/test_pattern.py +148 -0
  43. diogenesis_sdk-0.1.0/tests/test_policy_engine.py +92 -0
  44. diogenesis_sdk-0.1.0/tests/test_propagation.py +83 -0
  45. diogenesis_sdk-0.1.0/tests/test_scheduler.py +88 -0
  46. diogenesis_sdk-0.1.0/tests/test_subprocess_hook.py +60 -0
  47. diogenesis_sdk-0.1.0/tests/test_swarm.py +119 -0
  48. diogenesis_sdk-0.1.0/tests/test_voltage.py +117 -0
  49. diogenesis_sdk-0.1.0/tests/test_xenobot.py +150 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Garry Anderson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,91 @@
1
+ Metadata-Version: 2.4
2
+ Name: diogenesis-sdk
3
+ Version: 0.1.0
4
+ Summary: Behavioral health for Python applications. Not signatures. Not rules. Coherence.
5
+ Author-email: Garry Anderson <prnt3dman1@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/prnt3dman1/diogenesis-sdk
8
+ Keywords: security,behavioral,monitoring,runtime,anomaly,detection
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Topic :: Security
12
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Requires-Python: >=3.9
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Dynamic: license-file
19
+
20
+ # Diogenesis SDK
21
+
22
+ **Behavioral health for Python applications.**
23
+
24
+ Not signature-based detection. Not rule-based blocking. Behavioral coherence.
25
+
26
+ ## Install
27
+
28
+ ```
29
+ pip install diogenesis-sdk
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ```python
35
+ import diogenesis_sdk
36
+
37
+ diogenesis_sdk.activate()
38
+ # your application runs normally — every import, file access,
39
+ # subprocess call, and network request is observed
40
+
41
+ print(diogenesis_sdk.status()) # what's being tracked
42
+ print(diogenesis_sdk.log(10)) # last 10 events
43
+ print(diogenesis_sdk.baseline()) # behavioral fingerprint (after 1000+ events)
44
+
45
+ diogenesis_sdk.deactivate() # cleanly restore all originals
46
+ ```
47
+
48
+ ## What It Does
49
+
50
+ Diogenesis intercepts every import, file access, subprocess call, and network request in your Python application. It classifies each as KNOWN, UNEXPECTED, or SUSPICIOUS based on behavioral patterns. After observing 1000+ events, it generates a behavioral baseline that defines what "normal" looks like. Deviations are anomalies — whether from attacks, bugs, or dependency rot.
51
+
52
+ ## Zero Dependencies
53
+
54
+ Diogenesis uses only the Python standard library. A security product with supply chain risk is a contradiction.
55
+
56
+ ## Philosophy
57
+
58
+ Inspired by Michael Levin's xenobot research: biological systems maintain health through behavioral coherence, not programmed rules. Diogenesis applies the same principle to software.
59
+
60
+ ## Design Principles
61
+
62
+ - **Never break the host application.** Every interceptor is try/except wrapped. If Diogenesis fails, your code runs normally.
63
+ - **Shadow mode only.** Diogenesis observes. It does not block. Policy enforcement comes in future versions.
64
+ - **Zero dependencies.** stdlib only. No supply chain risk.
65
+ - **Clean activate/deactivate.** One function call to start. One to stop. All originals restored.
66
+
67
+ ## Configuration
68
+
69
+ Pass a config dict to `activate()`:
70
+
71
+ ```python
72
+ diogenesis_sdk.activate({
73
+ "buffer_size": 5000,
74
+ "interceptors": {"import": True, "file": True, "subprocess": False, "network": True},
75
+ "whitelist": {
76
+ "import_modules": ["myapp", "mylib"],
77
+ "file_paths": ["/app/data/"],
78
+ "network_hosts": ["localhost", "api.myservice.com"],
79
+ },
80
+ "suspicious_patterns": {
81
+ "imports": ["ctypes"],
82
+ "subprocess_commands": ["rm -rf"],
83
+ },
84
+ })
85
+ ```
86
+
87
+ Or place a `diogenesis_sdk.json` file in your working directory.
88
+
89
+ ## License
90
+
91
+ MIT
@@ -0,0 +1,72 @@
1
+ # Diogenesis SDK
2
+
3
+ **Behavioral health for Python applications.**
4
+
5
+ Not signature-based detection. Not rule-based blocking. Behavioral coherence.
6
+
7
+ ## Install
8
+
9
+ ```
10
+ pip install diogenesis-sdk
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```python
16
+ import diogenesis_sdk
17
+
18
+ diogenesis_sdk.activate()
19
+ # your application runs normally — every import, file access,
20
+ # subprocess call, and network request is observed
21
+
22
+ print(diogenesis_sdk.status()) # what's being tracked
23
+ print(diogenesis_sdk.log(10)) # last 10 events
24
+ print(diogenesis_sdk.baseline()) # behavioral fingerprint (after 1000+ events)
25
+
26
+ diogenesis_sdk.deactivate() # cleanly restore all originals
27
+ ```
28
+
29
+ ## What It Does
30
+
31
+ Diogenesis intercepts every import, file access, subprocess call, and network request in your Python application. It classifies each as KNOWN, UNEXPECTED, or SUSPICIOUS based on behavioral patterns. After observing 1000+ events, it generates a behavioral baseline that defines what "normal" looks like. Deviations are anomalies — whether from attacks, bugs, or dependency rot.
32
+
33
+ ## Zero Dependencies
34
+
35
+ Diogenesis uses only the Python standard library. A security product with supply chain risk is a contradiction.
36
+
37
+ ## Philosophy
38
+
39
+ Inspired by Michael Levin's xenobot research: biological systems maintain health through behavioral coherence, not programmed rules. Diogenesis applies the same principle to software.
40
+
41
+ ## Design Principles
42
+
43
+ - **Never break the host application.** Every interceptor is try/except wrapped. If Diogenesis fails, your code runs normally.
44
+ - **Shadow mode only.** Diogenesis observes. It does not block. Policy enforcement comes in future versions.
45
+ - **Zero dependencies.** stdlib only. No supply chain risk.
46
+ - **Clean activate/deactivate.** One function call to start. One to stop. All originals restored.
47
+
48
+ ## Configuration
49
+
50
+ Pass a config dict to `activate()`:
51
+
52
+ ```python
53
+ diogenesis_sdk.activate({
54
+ "buffer_size": 5000,
55
+ "interceptors": {"import": True, "file": True, "subprocess": False, "network": True},
56
+ "whitelist": {
57
+ "import_modules": ["myapp", "mylib"],
58
+ "file_paths": ["/app/data/"],
59
+ "network_hosts": ["localhost", "api.myservice.com"],
60
+ },
61
+ "suspicious_patterns": {
62
+ "imports": ["ctypes"],
63
+ "subprocess_commands": ["rm -rf"],
64
+ },
65
+ })
66
+ ```
67
+
68
+ Or place a `diogenesis_sdk.json` file in your working directory.
69
+
70
+ ## License
71
+
72
+ MIT
@@ -0,0 +1,52 @@
1
+ """Diogenesis SDK — Behavioral health for Python applications.
2
+
3
+ Not signature-based detection. Not rule-based blocking. Behavioral coherence.
4
+
5
+ Usage:
6
+ import diogenesis_sdk
7
+
8
+ diogenesis_sdk.activate()
9
+ print(diogenesis_sdk.status()) # interceptor counts + field coherence
10
+ print(diogenesis_sdk.field_state()) # per-module voltage map
11
+ print(diogenesis_sdk.alerts()) # policy alerts
12
+ print(diogenesis_sdk.investigations()) # xenobot findings
13
+ print(diogenesis_sdk.threat_summary()) # threat/suspicious/benign counts
14
+ diogenesis_sdk.deactivate()
15
+ """
16
+
17
+ from .engine import DiogenesisEngine
18
+ from .policy.pattern import BehavioralPattern
19
+ from .timing.fibonacci import FibonacciClock
20
+ from .agents.xenobot import XenobotAgent
21
+
22
+ _engine = DiogenesisEngine()
23
+
24
+ activate = _engine.activate
25
+ deactivate = _engine.deactivate
26
+ status = _engine.status
27
+ log = _engine.log
28
+ baseline = _engine.baseline
29
+ configure = _engine.configure
30
+ alerts = _engine.alerts
31
+ alert_summary = _engine.alert_summary
32
+ escalations = _engine.escalations
33
+ add_pattern = _engine.add_pattern
34
+ evaluate_policies = _engine.evaluate_policies
35
+ field_state = _engine.field_state
36
+ module_voltage = _engine.module_voltage
37
+ voltage_history = _engine.voltage_history
38
+ connection_graph = _engine.connection_graph
39
+ create_scheduler = _engine.create_scheduler
40
+ investigations = _engine.investigations
41
+ threat_summary = _engine.threat_summary
42
+ add_agent = _engine.add_agent
43
+
44
+ __version__ = "0.1.0"
45
+ __author__ = "Garry Anderson"
46
+ __all__ = [
47
+ "activate", "deactivate", "status", "log", "baseline", "configure",
48
+ "alerts", "alert_summary", "escalations", "add_pattern", "evaluate_policies",
49
+ "field_state", "module_voltage", "voltage_history", "connection_graph",
50
+ "create_scheduler", "investigations", "threat_summary", "add_agent",
51
+ "BehavioralPattern", "FibonacciClock", "XenobotAgent",
52
+ ]
File without changes
@@ -0,0 +1,152 @@
1
+ """Xenobot swarm — coordinate multiple autonomous investigation agents."""
2
+
3
+ import os
4
+ from collections import deque
5
+
6
+ from .xenobot import XenobotAgent, Investigation
7
+
8
+
9
+ class XenobotSwarm:
10
+ """Coordinate multiple xenobot agents. Each specializes in a domain."""
11
+
12
+ def __init__(self):
13
+ self.agents = {}
14
+ self.investigation_log = deque(maxlen=2000)
15
+ self.shared_model = {}
16
+
17
+ def create_default_swarm(self):
18
+ """Create the standard 4-agent swarm."""
19
+ self.agents = {
20
+ "import_guardian": XenobotAgent("import_guardian", domain="import"),
21
+ "file_sentinel": XenobotAgent("file_sentinel", domain="file"),
22
+ "network_watcher": XenobotAgent("network_watcher", domain="network"),
23
+ "subprocess_monitor": XenobotAgent("subprocess_monitor", domain="subprocess"),
24
+ }
25
+
26
+ def add_agent(self, agent):
27
+ """Add a custom agent to the swarm."""
28
+ self.agents[agent.name] = agent
29
+
30
+ def remove_agent(self, name):
31
+ """Remove an agent by name."""
32
+ self.agents.pop(name, None)
33
+
34
+ def respond_to_alert(self, alert, context) -> list:
35
+ """Dispatch appropriate agent(s) to investigate an alert."""
36
+ results = []
37
+ matched_events = alert.get("matched_events", [])
38
+ event_types = set()
39
+ for evt in matched_events:
40
+ event_types.add(evt.get("type", "unknown"))
41
+
42
+ # Find agents whose domain matches any event type in the alert
43
+ dispatched = set()
44
+ for etype in event_types:
45
+ for name, agent in self.agents.items():
46
+ if agent.domain == etype and name not in dispatched:
47
+ dispatched.add(name)
48
+ # Use the first event of this agent's domain as trigger
49
+ trigger = next((e for e in matched_events if e.get("type") == etype), matched_events[0])
50
+ inv = agent.investigate(trigger, context)
51
+ self.investigation_log.append(inv)
52
+ results.append(inv)
53
+
54
+ # If no domain-specific agent matched, use first available agent
55
+ if not results and self.agents and matched_events:
56
+ agent = next(iter(self.agents.values()))
57
+ inv = agent.investigate(matched_events[0], context)
58
+ self.investigation_log.append(inv)
59
+ results.append(inv)
60
+
61
+ return results
62
+
63
+ def respond_to_voltage_drop(self, module_name, voltage, context) -> Investigation:
64
+ """Investigate a module with dangerously low voltage."""
65
+ # Determine the module's primary event type from recent events
66
+ recent = context.get("recent_events", [])
67
+ module_events = [e for e in recent if module_name in str(e.get("caller_file", ""))]
68
+
69
+ # Count event types for this module
70
+ type_counts = {}
71
+ for e in module_events[-50:]:
72
+ t = e.get("type", "unknown")
73
+ type_counts[t] = type_counts.get(t, 0) + 1
74
+
75
+ primary_type = max(type_counts, key=type_counts.get) if type_counts else "unknown"
76
+
77
+ # Find the right agent
78
+ agent = None
79
+ for a in self.agents.values():
80
+ if a.domain == primary_type:
81
+ agent = a
82
+ break
83
+ if agent is None and self.agents:
84
+ agent = next(iter(self.agents.values()))
85
+ if agent is None:
86
+ inv = Investigation()
87
+ inv.agent_name = "none"
88
+ inv.verdict = "SUSPICIOUS"
89
+ inv.reasoning = "No agents available"
90
+ return inv
91
+
92
+ # Create a synthetic trigger for the voltage drop
93
+ trigger = {
94
+ "type": primary_type,
95
+ "classification": "UNEXPECTED",
96
+ "caller_file": f"{module_name}.py",
97
+ "detail": {"voltage_drop": True, "voltage": voltage, "module": module_name},
98
+ }
99
+ inv = agent.investigate(trigger, context)
100
+ self.investigation_log.append(inv)
101
+ return inv
102
+
103
+ def get_findings(self, n=50, verdict=None) -> list:
104
+ """Return recent findings, optionally filtered by verdict."""
105
+ items = list(self.investigation_log)
106
+ if verdict:
107
+ items = [i for i in items if i.verdict == verdict]
108
+ return [i.to_dict() if hasattr(i, "to_dict") else i for i in items[-n:]]
109
+
110
+ def get_threat_summary(self) -> dict:
111
+ """Count of threats, suspicious, benign across the swarm."""
112
+ items = list(self.investigation_log)
113
+ counts = {"THREAT": 0, "SUSPICIOUS": 0, "BENIGN": 0}
114
+ for inv in items:
115
+ v = inv.verdict if hasattr(inv, "verdict") else "UNKNOWN"
116
+ counts[v] = counts.get(v, 0) + 1
117
+
118
+ agent_stats = {}
119
+ for name, agent in self.agents.items():
120
+ agent_stats[name] = dict(agent.stats)
121
+
122
+ return {
123
+ "threats": counts.get("THREAT", 0),
124
+ "suspicious": counts.get("SUSPICIOUS", 0),
125
+ "benign": counts.get("BENIGN", 0),
126
+ "total_investigations": len(items),
127
+ "agents": agent_stats,
128
+ }
129
+
130
+ def share_learning(self):
131
+ """Sync behavioral models across all agents.
132
+
133
+ When one agent learns a pattern is BENIGN, all agents learn it.
134
+ When one agent identifies a THREAT pattern, all agents watch for it.
135
+ """
136
+ # Merge all agent models into shared model
137
+ for agent in self.agents.values():
138
+ for phash, entry in agent.behavioral_model.items():
139
+ existing = self.shared_model.get(phash)
140
+ if existing is None or entry["last_seen"] > existing["last_seen"]:
141
+ self.shared_model[phash] = dict(entry)
142
+
143
+ # Distribute shared model back to all agents
144
+ for agent in self.agents.values():
145
+ for phash, entry in self.shared_model.items():
146
+ if phash not in agent.behavioral_model:
147
+ agent.behavioral_model[phash] = dict(entry)
148
+ else:
149
+ existing = agent.behavioral_model[phash]
150
+ if entry["last_seen"] > existing["last_seen"]:
151
+ existing["verdict"] = entry["verdict"]
152
+ existing["last_seen"] = entry["last_seen"]