zexus 1.6.2

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 (227) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +2513 -0
  3. package/bin/zexus +2 -0
  4. package/bin/zpics +2 -0
  5. package/bin/zpm +2 -0
  6. package/bin/zx +2 -0
  7. package/bin/zx-deploy +2 -0
  8. package/bin/zx-dev +2 -0
  9. package/bin/zx-run +2 -0
  10. package/package.json +66 -0
  11. package/scripts/README.md +24 -0
  12. package/scripts/postinstall.js +44 -0
  13. package/shared_config.json +24 -0
  14. package/src/README.md +1525 -0
  15. package/src/tests/run_zexus_tests.py +117 -0
  16. package/src/tests/test_all_phases.zx +346 -0
  17. package/src/tests/test_blockchain_features.zx +306 -0
  18. package/src/tests/test_complexity_features.zx +321 -0
  19. package/src/tests/test_core_integration.py +185 -0
  20. package/src/tests/test_phase10_ecosystem.zx +177 -0
  21. package/src/tests/test_phase1_modifiers.zx +87 -0
  22. package/src/tests/test_phase2_plugins.zx +80 -0
  23. package/src/tests/test_phase3_security.zx +97 -0
  24. package/src/tests/test_phase4_vfs.zx +116 -0
  25. package/src/tests/test_phase5_types.zx +117 -0
  26. package/src/tests/test_phase6_metaprogramming.zx +125 -0
  27. package/src/tests/test_phase7_optimization.zx +132 -0
  28. package/src/tests/test_phase9_advanced_types.zx +157 -0
  29. package/src/tests/test_security_features.py +419 -0
  30. package/src/tests/test_security_features.zx +276 -0
  31. package/src/tests/test_simple_zx.zx +1 -0
  32. package/src/tests/test_verification_simple.zx +69 -0
  33. package/src/zexus/__init__.py +28 -0
  34. package/src/zexus/__main__.py +5 -0
  35. package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
  36. package/src/zexus/__pycache__/advanced_types.cpython-312.pyc +0 -0
  37. package/src/zexus/__pycache__/builtin_modules.cpython-312.pyc +0 -0
  38. package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
  39. package/src/zexus/__pycache__/complexity_system.cpython-312.pyc +0 -0
  40. package/src/zexus/__pycache__/concurrency_system.cpython-312.pyc +0 -0
  41. package/src/zexus/__pycache__/config.cpython-312.pyc +0 -0
  42. package/src/zexus/__pycache__/dependency_injection.cpython-312.pyc +0 -0
  43. package/src/zexus/__pycache__/ecosystem.cpython-312.pyc +0 -0
  44. package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
  45. package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
  46. package/src/zexus/__pycache__/hybrid_orchestrator.cpython-312.pyc +0 -0
  47. package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
  48. package/src/zexus/__pycache__/metaprogramming.cpython-312.pyc +0 -0
  49. package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
  50. package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
  51. package/src/zexus/__pycache__/optimization.cpython-312.pyc +0 -0
  52. package/src/zexus/__pycache__/plugin_system.cpython-312.pyc +0 -0
  53. package/src/zexus/__pycache__/policy_engine.cpython-312.pyc +0 -0
  54. package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
  55. package/src/zexus/__pycache__/stdlib_integration.cpython-312.pyc +0 -0
  56. package/src/zexus/__pycache__/strategy_recovery.cpython-312.pyc +0 -0
  57. package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
  58. package/src/zexus/__pycache__/type_system.cpython-312.pyc +0 -0
  59. package/src/zexus/__pycache__/virtual_filesystem.cpython-312.pyc +0 -0
  60. package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  61. package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
  62. package/src/zexus/advanced_types.py +401 -0
  63. package/src/zexus/blockchain/__init__.py +40 -0
  64. package/src/zexus/blockchain/__pycache__/__init__.cpython-312.pyc +0 -0
  65. package/src/zexus/blockchain/__pycache__/crypto.cpython-312.pyc +0 -0
  66. package/src/zexus/blockchain/__pycache__/ledger.cpython-312.pyc +0 -0
  67. package/src/zexus/blockchain/__pycache__/transaction.cpython-312.pyc +0 -0
  68. package/src/zexus/blockchain/crypto.py +463 -0
  69. package/src/zexus/blockchain/ledger.py +255 -0
  70. package/src/zexus/blockchain/transaction.py +267 -0
  71. package/src/zexus/builtin_modules.py +284 -0
  72. package/src/zexus/builtin_plugins.py +317 -0
  73. package/src/zexus/capability_system.py +372 -0
  74. package/src/zexus/cli/__init__.py +2 -0
  75. package/src/zexus/cli/__pycache__/__init__.cpython-312.pyc +0 -0
  76. package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
  77. package/src/zexus/cli/main.py +707 -0
  78. package/src/zexus/cli/zpm.py +203 -0
  79. package/src/zexus/compare_interpreter_compiler.py +146 -0
  80. package/src/zexus/compiler/__init__.py +169 -0
  81. package/src/zexus/compiler/__pycache__/__init__.cpython-312.pyc +0 -0
  82. package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
  83. package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
  84. package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  85. package/src/zexus/compiler/bytecode.py +266 -0
  86. package/src/zexus/compiler/compat_runtime.py +277 -0
  87. package/src/zexus/compiler/lexer.py +257 -0
  88. package/src/zexus/compiler/parser.py +779 -0
  89. package/src/zexus/compiler/semantic.py +118 -0
  90. package/src/zexus/compiler/zexus_ast.py +454 -0
  91. package/src/zexus/complexity_system.py +575 -0
  92. package/src/zexus/concurrency_system.py +493 -0
  93. package/src/zexus/config.py +201 -0
  94. package/src/zexus/crypto_bridge.py +19 -0
  95. package/src/zexus/dependency_injection.py +423 -0
  96. package/src/zexus/ecosystem.py +434 -0
  97. package/src/zexus/environment.py +101 -0
  98. package/src/zexus/environment_manager.py +119 -0
  99. package/src/zexus/error_reporter.py +314 -0
  100. package/src/zexus/evaluator/__init__.py +12 -0
  101. package/src/zexus/evaluator/__pycache__/__init__.cpython-312.pyc +0 -0
  102. package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
  103. package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
  104. package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
  105. package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
  106. package/src/zexus/evaluator/__pycache__/integration.cpython-312.pyc +0 -0
  107. package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
  108. package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
  109. package/src/zexus/evaluator/bytecode_compiler.py +700 -0
  110. package/src/zexus/evaluator/core.py +891 -0
  111. package/src/zexus/evaluator/expressions.py +827 -0
  112. package/src/zexus/evaluator/functions.py +3989 -0
  113. package/src/zexus/evaluator/integration.py +396 -0
  114. package/src/zexus/evaluator/statements.py +4303 -0
  115. package/src/zexus/evaluator/utils.py +126 -0
  116. package/src/zexus/evaluator_original.py +2041 -0
  117. package/src/zexus/external_bridge.py +16 -0
  118. package/src/zexus/find_affected_imports.sh +155 -0
  119. package/src/zexus/hybrid_orchestrator.py +152 -0
  120. package/src/zexus/input_validation.py +259 -0
  121. package/src/zexus/lexer.py +571 -0
  122. package/src/zexus/logging.py +89 -0
  123. package/src/zexus/lsp/__init__.py +9 -0
  124. package/src/zexus/lsp/completion_provider.py +207 -0
  125. package/src/zexus/lsp/definition_provider.py +22 -0
  126. package/src/zexus/lsp/hover_provider.py +71 -0
  127. package/src/zexus/lsp/server.py +269 -0
  128. package/src/zexus/lsp/symbol_provider.py +31 -0
  129. package/src/zexus/metaprogramming.py +321 -0
  130. package/src/zexus/module_cache.py +89 -0
  131. package/src/zexus/module_manager.py +107 -0
  132. package/src/zexus/object.py +973 -0
  133. package/src/zexus/optimization.py +424 -0
  134. package/src/zexus/parser/__init__.py +31 -0
  135. package/src/zexus/parser/__pycache__/__init__.cpython-312.pyc +0 -0
  136. package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
  137. package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
  138. package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
  139. package/src/zexus/parser/integration.py +86 -0
  140. package/src/zexus/parser/parser.py +3977 -0
  141. package/src/zexus/parser/strategy_context.py +7254 -0
  142. package/src/zexus/parser/strategy_structural.py +1033 -0
  143. package/src/zexus/persistence.py +391 -0
  144. package/src/zexus/plugin_system.py +290 -0
  145. package/src/zexus/policy_engine.py +365 -0
  146. package/src/zexus/profiler/__init__.py +5 -0
  147. package/src/zexus/profiler/profiler.py +233 -0
  148. package/src/zexus/purity_system.py +398 -0
  149. package/src/zexus/runtime/__init__.py +20 -0
  150. package/src/zexus/runtime/async_runtime.py +324 -0
  151. package/src/zexus/search_old_imports.sh +65 -0
  152. package/src/zexus/security.py +1407 -0
  153. package/src/zexus/stack_trace.py +233 -0
  154. package/src/zexus/stdlib/__init__.py +27 -0
  155. package/src/zexus/stdlib/blockchain.py +341 -0
  156. package/src/zexus/stdlib/compression.py +167 -0
  157. package/src/zexus/stdlib/crypto.py +124 -0
  158. package/src/zexus/stdlib/datetime.py +163 -0
  159. package/src/zexus/stdlib/db_mongo.py +199 -0
  160. package/src/zexus/stdlib/db_mysql.py +162 -0
  161. package/src/zexus/stdlib/db_postgres.py +163 -0
  162. package/src/zexus/stdlib/db_sqlite.py +133 -0
  163. package/src/zexus/stdlib/encoding.py +230 -0
  164. package/src/zexus/stdlib/fs.py +195 -0
  165. package/src/zexus/stdlib/http.py +219 -0
  166. package/src/zexus/stdlib/http_server.py +248 -0
  167. package/src/zexus/stdlib/json_module.py +61 -0
  168. package/src/zexus/stdlib/math.py +360 -0
  169. package/src/zexus/stdlib/os_module.py +265 -0
  170. package/src/zexus/stdlib/regex.py +148 -0
  171. package/src/zexus/stdlib/sockets.py +253 -0
  172. package/src/zexus/stdlib/test_framework.zx +208 -0
  173. package/src/zexus/stdlib/test_runner.zx +119 -0
  174. package/src/zexus/stdlib_integration.py +341 -0
  175. package/src/zexus/strategy_recovery.py +256 -0
  176. package/src/zexus/syntax_validator.py +356 -0
  177. package/src/zexus/testing/zpics.py +407 -0
  178. package/src/zexus/testing/zpics_runtime.py +369 -0
  179. package/src/zexus/type_system.py +374 -0
  180. package/src/zexus/validation_system.py +569 -0
  181. package/src/zexus/virtual_filesystem.py +355 -0
  182. package/src/zexus/vm/__init__.py +8 -0
  183. package/src/zexus/vm/__pycache__/__init__.cpython-312.pyc +0 -0
  184. package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
  185. package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
  186. package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
  187. package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
  188. package/src/zexus/vm/__pycache__/memory_manager.cpython-312.pyc +0 -0
  189. package/src/zexus/vm/__pycache__/memory_pool.cpython-312.pyc +0 -0
  190. package/src/zexus/vm/__pycache__/optimizer.cpython-312.pyc +0 -0
  191. package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
  192. package/src/zexus/vm/__pycache__/peephole_optimizer.cpython-312.pyc +0 -0
  193. package/src/zexus/vm/__pycache__/profiler.cpython-312.pyc +0 -0
  194. package/src/zexus/vm/__pycache__/register_allocator.cpython-312.pyc +0 -0
  195. package/src/zexus/vm/__pycache__/register_vm.cpython-312.pyc +0 -0
  196. package/src/zexus/vm/__pycache__/ssa_converter.cpython-312.pyc +0 -0
  197. package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
  198. package/src/zexus/vm/async_optimizer.py +420 -0
  199. package/src/zexus/vm/bytecode.py +428 -0
  200. package/src/zexus/vm/bytecode_converter.py +297 -0
  201. package/src/zexus/vm/cache.py +532 -0
  202. package/src/zexus/vm/jit.py +720 -0
  203. package/src/zexus/vm/memory_manager.py +520 -0
  204. package/src/zexus/vm/memory_pool.py +511 -0
  205. package/src/zexus/vm/optimizer.py +478 -0
  206. package/src/zexus/vm/parallel_vm.py +899 -0
  207. package/src/zexus/vm/peephole_optimizer.py +452 -0
  208. package/src/zexus/vm/profiler.py +527 -0
  209. package/src/zexus/vm/register_allocator.py +462 -0
  210. package/src/zexus/vm/register_vm.py +520 -0
  211. package/src/zexus/vm/ssa_converter.py +757 -0
  212. package/src/zexus/vm/vm.py +1392 -0
  213. package/src/zexus/zexus_ast.py +1782 -0
  214. package/src/zexus/zexus_token.py +253 -0
  215. package/src/zexus/zpm/__init__.py +15 -0
  216. package/src/zexus/zpm/installer.py +116 -0
  217. package/src/zexus/zpm/package_manager.py +208 -0
  218. package/src/zexus/zpm/publisher.py +98 -0
  219. package/src/zexus/zpm/registry.py +110 -0
  220. package/src/zexus.egg-info/PKG-INFO +2235 -0
  221. package/src/zexus.egg-info/SOURCES.txt +876 -0
  222. package/src/zexus.egg-info/dependency_links.txt +1 -0
  223. package/src/zexus.egg-info/entry_points.txt +3 -0
  224. package/src/zexus.egg-info/not-zip-safe +1 -0
  225. package/src/zexus.egg-info/requires.txt +14 -0
  226. package/src/zexus.egg-info/top_level.txt +2 -0
  227. package/zexus.json +14 -0
@@ -0,0 +1,365 @@
1
+ # src/zexus/policy_engine.py
2
+ """
3
+ Policy-as-Code Engine for Zexus PROTECT Feature
4
+ Implements declarative security policy injection with VERIFY and RESTRICT
5
+ """
6
+
7
+ from typing import Dict, List, Any, Callable, Optional
8
+ from .object import Object, Boolean as BooleanObj, String, Integer, NULL, EvaluationError
9
+
10
+
11
+ # ===============================================
12
+ # POLICY RULE TYPES
13
+ # ===============================================
14
+
15
+ class PolicyRule:
16
+ """Base class for policy rules"""
17
+
18
+ def __init__(self, description: str = ""):
19
+ self.description = description
20
+
21
+ def evaluate(self, context: Dict[str, Any]) -> tuple[bool, str]:
22
+ """
23
+ Evaluate the policy rule
24
+ Returns: (success: bool, message: str)
25
+ """
26
+ raise NotImplementedError("Subclasses must implement evaluate()")
27
+
28
+
29
+ class VerifyRule(PolicyRule):
30
+ """VERIFY rule - checks a boolean condition"""
31
+
32
+ def __init__(self, condition_fn: Callable, description: str = "Verification check"):
33
+ super().__init__(description)
34
+ self.condition_fn = condition_fn
35
+
36
+ def evaluate(self, context: Dict[str, Any]) -> tuple[bool, str]:
37
+ try:
38
+ result = self.condition_fn(context)
39
+ success = result.value if isinstance(result, BooleanObj) else bool(result)
40
+ message = self.description if not success else ""
41
+ return success, message
42
+ except Exception as e:
43
+ return False, f"Verification failed: {str(e)}"
44
+
45
+
46
+ class RestrictRule(PolicyRule):
47
+ """RESTRICT rule - applies constraints to data"""
48
+
49
+ def __init__(self, field_name: str, constraints: List[Callable], description: str = ""):
50
+ super().__init__(description)
51
+ self.field_name = field_name
52
+ self.constraints = constraints
53
+
54
+ def evaluate(self, context: Dict[str, Any]) -> tuple[bool, str]:
55
+ value = context.get(self.field_name)
56
+
57
+ if value is None:
58
+ return False, f"Field '{self.field_name}' not found in context"
59
+
60
+ for constraint in self.constraints:
61
+ try:
62
+ result = constraint(value, context)
63
+ passed = result.value if isinstance(result, BooleanObj) else bool(result)
64
+ if not passed:
65
+ return False, f"Constraint failed for '{self.field_name}'"
66
+ except Exception as e:
67
+ return False, f"Constraint evaluation error: {str(e)}"
68
+
69
+ return True, ""
70
+
71
+
72
+ # ===============================================
73
+ # PROTECTION POLICY
74
+ # ===============================================
75
+
76
+ class ProtectionPolicy:
77
+ """Represents a complete protection policy for a target"""
78
+
79
+ def __init__(self, target_name: str, enforcement_level: str = "strict"):
80
+ self.target_name = target_name
81
+ self.enforcement_level = enforcement_level # "strict", "warn", "audit", "permissive"
82
+ self.rules: List[PolicyRule] = []
83
+ self.middleware_chain: List[Callable] = []
84
+ self.on_violation: Optional[Callable] = None
85
+ self.audit_log: List[Dict[str, Any]] = []
86
+
87
+ def add_rule(self, rule: PolicyRule):
88
+ """Add a policy rule"""
89
+ self.rules.append(rule)
90
+
91
+ def add_middleware(self, middleware: Callable):
92
+ """Add middleware to the protection chain"""
93
+ self.middleware_chain.append(middleware)
94
+
95
+ def set_violation_handler(self, handler: Callable):
96
+ """Set handler for policy violations"""
97
+ self.on_violation = handler
98
+
99
+ def evaluate(self, context: Dict[str, Any]) -> tuple[bool, List[str]]:
100
+ """
101
+ Evaluate all policy rules
102
+ Returns: (all_passed: bool, violation_messages: List[str])
103
+ """
104
+ violations = []
105
+
106
+ for rule in self.rules:
107
+ passed, message = rule.evaluate(context)
108
+
109
+ if not passed:
110
+ violations.append(message)
111
+
112
+ # Log the violation
113
+ self._audit_violation(rule, message, context)
114
+
115
+ # Handle based on enforcement level
116
+ if self.enforcement_level == "strict":
117
+ # Strict mode: fail immediately
118
+ return False, violations
119
+ elif self.enforcement_level == "warn":
120
+ # Warn mode: continue but collect violations
121
+ print(f"⚠️ Policy Warning ({self.target_name}): {message}")
122
+ elif self.enforcement_level == "audit":
123
+ # Audit mode: log only, allow execution
124
+ pass
125
+ # permissive mode: do nothing
126
+
127
+ # All rules passed or enforcement allows it
128
+ all_passed = len(violations) == 0
129
+ return all_passed, violations
130
+
131
+ def execute_middleware(self, context: Dict[str, Any], original_fn: Callable):
132
+ """Execute middleware chain"""
133
+ # Build middleware chain
134
+ def final_handler():
135
+ return original_fn(context)
136
+
137
+ # Wrap with each middleware (reverse order for proper nesting)
138
+ handler = final_handler
139
+ for middleware in reversed(self.middleware_chain):
140
+ current_handler = handler
141
+ handler = lambda ctx=context, mw=middleware, h=current_handler: mw(ctx, h)
142
+
143
+ # Execute the chain
144
+ return handler()
145
+
146
+ def _audit_violation(self, rule: PolicyRule, message: str, context: Dict[str, Any]):
147
+ """Log a policy violation"""
148
+ import time
149
+ self.audit_log.append({
150
+ 'timestamp': time.time(),
151
+ 'target': self.target_name,
152
+ 'rule': rule.description,
153
+ 'message': message,
154
+ 'context_keys': list(context.keys()),
155
+ 'enforcement_level': self.enforcement_level
156
+ })
157
+
158
+ def get_audit_log(self) -> List[Dict[str, Any]]:
159
+ """Get audit log"""
160
+ return self.audit_log
161
+
162
+
163
+ # ===============================================
164
+ # POLICY REGISTRY
165
+ # ===============================================
166
+
167
+ class PolicyRegistry:
168
+ """Global registry for protection policies"""
169
+
170
+ def __init__(self):
171
+ self.policies: Dict[str, ProtectionPolicy] = {}
172
+ self.protected_functions: Dict[str, Callable] = {}
173
+
174
+ def register_policy(self, target_name: str, policy: ProtectionPolicy):
175
+ """Register a protection policy for a target"""
176
+ self.policies[target_name] = policy
177
+
178
+ def get_policy(self, target_name: str) -> Optional[ProtectionPolicy]:
179
+ """Get policy for a target"""
180
+ return self.policies.get(target_name)
181
+
182
+ def protect_function(self, func_name: str, original_fn: Callable, policy: ProtectionPolicy):
183
+ """Wrap a function with policy enforcement"""
184
+ self.protected_functions[func_name] = original_fn
185
+ self.register_policy(func_name, policy)
186
+
187
+ def execute_protected(self, func_name: str, context: Dict[str, Any]):
188
+ """Execute a protected function with policy checks"""
189
+ policy = self.get_policy(func_name)
190
+ original_fn = self.protected_functions.get(func_name)
191
+
192
+ if not policy or not original_fn:
193
+ raise ValueError(f"Function '{func_name}' not registered for protection")
194
+
195
+ # Evaluate policy
196
+ passed, violations = policy.evaluate(context)
197
+
198
+ if not passed and policy.enforcement_level == "strict":
199
+ error_msg = "; ".join(violations)
200
+ if policy.on_violation:
201
+ return policy.on_violation(violations, context)
202
+ raise EvaluationError(f"Policy violation for {func_name}: {error_msg}")
203
+
204
+ # Execute middleware chain
205
+ return policy.execute_middleware(context, original_fn)
206
+
207
+ def list_protected_targets(self) -> List[str]:
208
+ """List all protected targets"""
209
+ return list(self.policies.keys())
210
+
211
+ def get_audit_summary(self) -> Dict[str, Any]:
212
+ """Get summary of all audit logs"""
213
+ total_violations = 0
214
+ by_target = {}
215
+
216
+ for target_name, policy in self.policies.items():
217
+ violations = policy.get_audit_log()
218
+ total_violations += len(violations)
219
+ by_target[target_name] = len(violations)
220
+
221
+ return {
222
+ 'total_violations': total_violations,
223
+ 'by_target': by_target,
224
+ 'protected_targets': len(self.policies)
225
+ }
226
+
227
+
228
+ # Global policy registry
229
+ _policy_registry = PolicyRegistry()
230
+
231
+
232
+ def get_policy_registry() -> PolicyRegistry:
233
+ """Get the global policy registry"""
234
+ return _policy_registry
235
+
236
+
237
+ # ===============================================
238
+ # POLICY BUILDER (DSL Support)
239
+ # ===============================================
240
+
241
+ class PolicyBuilder:
242
+ """Builder for creating policies from PROTECT blocks"""
243
+
244
+ def __init__(self, target_name: str):
245
+ self.policy = ProtectionPolicy(target_name)
246
+
247
+ def add_verify_condition(self, condition_fn: Callable, description: str = ""):
248
+ """Add a VERIFY rule"""
249
+ rule = VerifyRule(condition_fn, description)
250
+ self.policy.add_rule(rule)
251
+ return self
252
+
253
+ def add_restrict_constraint(self, field_name: str, constraints: List[Callable], description: str = ""):
254
+ """Add a RESTRICT rule"""
255
+ rule = RestrictRule(field_name, constraints, description)
256
+ self.policy.add_rule(rule)
257
+ return self
258
+
259
+ def set_enforcement(self, level: str):
260
+ """Set enforcement level"""
261
+ self.policy.enforcement_level = level
262
+ return self
263
+
264
+ def with_middleware(self, middleware: Callable):
265
+ """Add middleware"""
266
+ self.policy.add_middleware(middleware)
267
+ return self
268
+
269
+ def on_violation(self, handler: Callable):
270
+ """Set violation handler"""
271
+ self.policy.set_violation_handler(handler)
272
+ return self
273
+
274
+ def build(self) -> ProtectionPolicy:
275
+ """Build and return the policy"""
276
+ return self.policy
277
+
278
+
279
+ # ===============================================
280
+ # BUILT-IN POLICY CONSTRAINTS
281
+ # ===============================================
282
+
283
+ def length_constraint(min_len: int = 0, max_len: int = float('inf')):
284
+ """Create a length constraint for strings"""
285
+ def check(value: Object, context: Dict[str, Any]) -> BooleanObj:
286
+ if isinstance(value, String):
287
+ length = len(value.value)
288
+ return BooleanObj(min_len <= length <= max_len)
289
+ return BooleanObj(False)
290
+ return check
291
+
292
+
293
+ def contains_constraint(substring: str):
294
+ """Create a contains constraint for strings"""
295
+ def check(value: Object, context: Dict[str, Any]) -> BooleanObj:
296
+ if isinstance(value, String):
297
+ return BooleanObj(substring in value.value)
298
+ return BooleanObj(False)
299
+ return check
300
+
301
+
302
+ def range_constraint(min_val: int = float('-inf'), max_val: int = float('inf')):
303
+ """Create a range constraint for numbers"""
304
+ def check(value: Object, context: Dict[str, Any]) -> BooleanObj:
305
+ if isinstance(value, Integer):
306
+ return BooleanObj(min_val <= value.value <= max_val)
307
+ return BooleanObj(False)
308
+ return check
309
+
310
+
311
+ def equality_constraint(expected_value: Any):
312
+ """Create an equality constraint"""
313
+ def check(value: Object, context: Dict[str, Any]) -> BooleanObj:
314
+ if hasattr(value, 'value'):
315
+ return BooleanObj(value.value == expected_value)
316
+ return BooleanObj(value == expected_value)
317
+ return check
318
+
319
+
320
+ def caller_constraint(allowed_callers: List[str]):
321
+ """Create a constraint checking TX.caller"""
322
+ def check(value: Object, context: Dict[str, Any]) -> BooleanObj:
323
+ caller = context.get('TX', {}).get('caller', '')
324
+ if isinstance(caller, String):
325
+ caller = caller.value
326
+ return BooleanObj(caller in allowed_callers)
327
+ return check
328
+
329
+
330
+ # ===============================================
331
+ # UTILITY FUNCTIONS
332
+ # ===============================================
333
+
334
+ def create_policy(target_name: str) -> PolicyBuilder:
335
+ """Create a new policy builder"""
336
+ return PolicyBuilder(target_name)
337
+
338
+
339
+ def protect_target(target_name: str, policy: ProtectionPolicy, original_fn: Callable):
340
+ """Register a target with protection policy"""
341
+ registry = get_policy_registry()
342
+ registry.protect_function(target_name, original_fn, policy)
343
+
344
+
345
+ def check_policy(target_name: str, context: Dict[str, Any]) -> tuple[bool, List[str]]:
346
+ """Check if context passes policy for target"""
347
+ registry = get_policy_registry()
348
+ policy = registry.get_policy(target_name)
349
+
350
+ if not policy:
351
+ return True, [] # No policy means no restrictions
352
+
353
+ return policy.evaluate(context)
354
+
355
+
356
+ def execute_protected(target_name: str, context: Dict[str, Any]):
357
+ """Execute a protected function"""
358
+ registry = get_policy_registry()
359
+ return registry.execute_protected(target_name, context)
360
+
361
+
362
+ def get_audit_summary() -> Dict[str, Any]:
363
+ """Get audit summary for all policies"""
364
+ registry = get_policy_registry()
365
+ return registry.get_audit_summary()
@@ -0,0 +1,5 @@
1
+ """Zexus Performance Profiler."""
2
+
3
+ from .profiler import Profiler, ProfileReport
4
+
5
+ __all__ = ['Profiler', 'ProfileReport']
@@ -0,0 +1,233 @@
1
+ """Performance profiler for Zexus code."""
2
+
3
+ import time
4
+ import tracemalloc
5
+ from typing import Dict, List, Any
6
+ from dataclasses import dataclass, field
7
+ from collections import defaultdict
8
+
9
+
10
+ @dataclass
11
+ class FunctionProfile:
12
+ """Profile data for a function."""
13
+ name: str
14
+ calls: int = 0
15
+ total_time: float = 0.0
16
+ self_time: float = 0.0
17
+ memory_allocated: int = 0
18
+ memory_peak: int = 0
19
+
20
+
21
+ @dataclass
22
+ class ProfileReport:
23
+ """Complete profiling report."""
24
+ total_time: float
25
+ total_calls: int
26
+ memory_peak: int
27
+ functions: Dict[str, FunctionProfile] = field(default_factory=dict)
28
+ hotspots: List[FunctionProfile] = field(default_factory=list)
29
+
30
+ def to_dict(self) -> Dict[str, Any]:
31
+ """Convert report to dictionary."""
32
+ return {
33
+ 'total_time': self.total_time,
34
+ 'total_calls': self.total_calls,
35
+ 'memory_peak': self.memory_peak,
36
+ 'functions': {
37
+ name: {
38
+ 'calls': prof.calls,
39
+ 'total_time': prof.total_time,
40
+ 'self_time': prof.self_time,
41
+ 'memory_allocated': prof.memory_allocated,
42
+ 'memory_peak': prof.memory_peak
43
+ }
44
+ for name, prof in self.functions.items()
45
+ },
46
+ 'hotspots': [
47
+ {
48
+ 'name': prof.name,
49
+ 'calls': prof.calls,
50
+ 'total_time': prof.total_time,
51
+ 'self_time': prof.self_time
52
+ }
53
+ for prof in self.hotspots
54
+ ]
55
+ }
56
+
57
+
58
+ class Profiler:
59
+ """Performance profiler for Zexus code execution."""
60
+
61
+ def __init__(self):
62
+ self.enabled = False
63
+ self.start_time = 0.0
64
+ self.functions = {}
65
+ self.call_stack = []
66
+ self.memory_enabled = False
67
+
68
+ def start(self, enable_memory: bool = True):
69
+ """Start profiling."""
70
+ self.enabled = True
71
+ self.memory_enabled = enable_memory
72
+ self.start_time = time.time()
73
+ self.functions = {}
74
+ self.call_stack = []
75
+
76
+ if enable_memory:
77
+ tracemalloc.start()
78
+
79
+ def stop(self) -> ProfileReport:
80
+ """Stop profiling and generate report."""
81
+ self.enabled = False
82
+ total_time = time.time() - self.start_time
83
+
84
+ memory_peak = 0
85
+ if self.memory_enabled:
86
+ _, peak = tracemalloc.get_traced_memory()
87
+ memory_peak = peak
88
+ tracemalloc.stop()
89
+
90
+ # Calculate total calls
91
+ total_calls = sum(prof.calls for prof in self.functions.values())
92
+
93
+ # Identify hotspots (functions taking most time)
94
+ hotspots = sorted(
95
+ self.functions.values(),
96
+ key=lambda p: p.total_time,
97
+ reverse=True
98
+ )[:10] # Top 10 hotspots
99
+
100
+ return ProfileReport(
101
+ total_time=total_time,
102
+ total_calls=total_calls,
103
+ memory_peak=memory_peak,
104
+ functions=self.functions,
105
+ hotspots=hotspots
106
+ )
107
+
108
+ def enter_function(self, name: str):
109
+ """Record entering a function."""
110
+ if not self.enabled:
111
+ return
112
+
113
+ if name not in self.functions:
114
+ self.functions[name] = FunctionProfile(name=name)
115
+
116
+ profile = self.functions[name]
117
+ profile.calls += 1
118
+
119
+ # Record memory if enabled
120
+ if self.memory_enabled:
121
+ current, _ = tracemalloc.get_traced_memory()
122
+ profile.memory_allocated = current
123
+
124
+ # Push onto call stack
125
+ self.call_stack.append({
126
+ 'name': name,
127
+ 'start_time': time.time(),
128
+ 'start_memory': profile.memory_allocated if self.memory_enabled else 0
129
+ })
130
+
131
+ def exit_function(self, name: str):
132
+ """Record exiting a function."""
133
+ if not self.enabled or not self.call_stack:
134
+ return
135
+
136
+ # Pop from call stack
137
+ call_info = self.call_stack.pop()
138
+
139
+ if call_info['name'] != name:
140
+ # Stack mismatch - log warning
141
+ import logging
142
+ logger = logging.getLogger(__name__)
143
+ logger.warning(f"Profile stack mismatch. Expected {call_info['name']}, got {name}")
144
+ return
145
+
146
+ # Calculate elapsed time
147
+ elapsed = time.time() - call_info['start_time']
148
+
149
+ profile = self.functions[name]
150
+ profile.total_time += elapsed
151
+ profile.self_time += elapsed
152
+
153
+ # Update memory if enabled
154
+ if self.memory_enabled:
155
+ current, peak = tracemalloc.get_traced_memory()
156
+ profile.memory_peak = max(profile.memory_peak, peak)
157
+
158
+ # Subtract time from parent if exists
159
+ if self.call_stack:
160
+ parent_name = self.call_stack[-1]['name']
161
+ if parent_name in self.functions:
162
+ self.functions[parent_name].self_time -= elapsed
163
+
164
+ def print_report(self, report: ProfileReport, top_n: int = 20):
165
+ """Print profiling report."""
166
+ print("\n" + "="*80)
167
+ print("ZEXUS PERFORMANCE PROFILE REPORT")
168
+ print("="*80)
169
+ print(f"\nTotal Time: {report.total_time:.4f} seconds")
170
+ print(f"Total Calls: {report.total_calls}")
171
+ print(f"Peak Memory: {report.memory_peak / 1024 / 1024:.2f} MB")
172
+
173
+ print(f"\n{'Function':<40} {'Calls':>10} {'Total Time':>15} {'Self Time':>15} {'Avg Time':>15}")
174
+ print("-"*100)
175
+
176
+ # Sort by total time
177
+ sorted_functions = sorted(
178
+ report.functions.values(),
179
+ key=lambda p: p.total_time,
180
+ reverse=True
181
+ )
182
+
183
+ for prof in sorted_functions[:top_n]:
184
+ avg_time = prof.total_time / prof.calls if prof.calls > 0 else 0
185
+ print(f"{prof.name:<40} {prof.calls:>10} {prof.total_time:>15.4f}s {prof.self_time:>15.4f}s {avg_time:>15.6f}s")
186
+
187
+ print("\n" + "="*80)
188
+ print("TOP HOTSPOTS (by total time)")
189
+ print("="*80)
190
+
191
+ for i, prof in enumerate(report.hotspots[:10], 1):
192
+ pct = (prof.total_time / report.total_time * 100) if report.total_time > 0 else 0
193
+ print(f"{i}. {prof.name}: {prof.total_time:.4f}s ({pct:.1f}%)")
194
+
195
+ print("="*80 + "\n")
196
+
197
+
198
+ # Global profiler instance
199
+ _profiler = Profiler()
200
+
201
+
202
+ def start_profiling(enable_memory: bool = True):
203
+ """Start global profiler."""
204
+ _profiler.start(enable_memory)
205
+
206
+
207
+ def stop_profiling() -> ProfileReport:
208
+ """Stop global profiler and get report."""
209
+ return _profiler.stop()
210
+
211
+
212
+ def print_profile():
213
+ """Print current profile."""
214
+ report = stop_profiling()
215
+ _profiler.print_report(report)
216
+ return report
217
+
218
+
219
+ def profile_function(func):
220
+ """Decorator to profile a function."""
221
+ def wrapper(*args, **kwargs):
222
+ _profiler.enter_function(func.__name__)
223
+ try:
224
+ result = func(*args, **kwargs)
225
+ return result
226
+ finally:
227
+ _profiler.exit_function(func.__name__)
228
+ return wrapper
229
+
230
+
231
+ def get_profiler() -> Profiler:
232
+ """Get global profiler instance."""
233
+ return _profiler